O presente texto explorará brevemente como acessar e manipular alguns dados sobre a questão racial na região central do município de São Paulo. Mais especificamente, o foco recairá sobre a distribuição espacial da população negra residente na região da Liberdade ao longo do tempo.
Para isso, dentre as diferentes bases disponíveis, optou-se por utilizar os dados do censo demográfico brasileiro, produzidos e disponibilizados pelo IBGE. Tal escolha reside na possibilidade de:
Replicar a análise para diferentes partes do território brasileiro (reprodutibilidade);
Realizar o resgate histórico da temática (cobertura temporal) e
Observar a distribuição do fenômeno espacial (cobertura espacial).
A análise proposta fará uso dos microdados censitários. Para uma versão similar baseada nos setores censitários, veja essa outra postagem (CRIAR LINK). Por fim, uma análise integrando ambos os dados, microdados e dados agregados por setor censitário, pode ser vista aqui (CRIAR LINK).
Antes da exploração proposta, vale mencionar que dois pilares conduzem a análise proposta: i) a busca por uma construção de caráter mais didático e não necessariamente extensiva1, e, ii) o uso das chamadas boas práticas para a manipulação de dados. Sem negar a importância da eficiência que as consultas e códigos devem perseguir, privilegia-se uma construção mais gradual, incremental e transparente - tarefa em muito facilitada pela concepção e ferramentas que compõem o Tidyverse. Ressalte-se, ainda, que um dos horizontes que guiam o presente esforço é o da Ciência Aberta.
Colocando a mão na massa: preparando o ambiente
Uma prática bastante usual ao escrever códigos no R consiste em “declarar/ativar” os pacotes (de funções) no início do script - por vezes isso também ocorre com as variáveis que serão utilizadas ao longo do percurso. Ainda que não seja obrigatória, essa prática permite que as funções sejam utilizadas sem que se explicite o nome do pacote (no R, para declarar o pacote e uma de suas funções segue-se a seguinte forma: pacote::função).
A seguir, duas formas para instalar e ativar os pacotes necessários são apresentadas. Gerando o mesmo resultado (ativação dos pacotes), a diferença entre a primeira forma (1st Way) e a segunda (2nd Way) é que na última o código checa os pacotes presentes no ambiente local/computador do usuário e apenas instala os que ainda não foram baixados. Já no primeiro caso, mesmo que o pacote já esteja instalado, o comando baixará novamente o seu conteúdo e o reinstalará. Note: para tornar mais claro o que está ocorrendo no segundo caminho de instalação, optou-se por inserir mensagens indicando se o pacote já estava instalado ou não (graças ao uso do comando print(“mensagem_a_ser_exibida”)). Observe, ainda, que o símbolo # é utilizado para a inserção de comentários no código, algo tido como uma boa prática. Ou seja, sempre que se fizer uso desse recurso, o conteúdo que vier imediatamente após ele será “ignorado”
Nota
O uso de comentários proporciona uma maior inteligibilidade do código e conversa diretamente com a possibilidade de reprodutibilidade do trabalho. Para exemplificar o ponto, pense que você e/ou outras pessoas podem revisitar o código no futuro e alguns detalhes podem não estar mais tão claros.
Code
# Save all the packages needed inside an object ("folder")1pckgs <-c("tidyverse", "sf", "here", "janitor", "arrow", "censobr", "geobr", "sidrar", "gt", "devtools", "mapview", "terra", "patchwork", "RColorBrewer", "leafsync")# 1st way ## Install all the packages previously selected2# install.packages(pckgs, dependencies = TRUE)## Load the packages. This make all the packages functionalities available 3# lapply(pckgs, library, character.only = TRUE)# 2nd way## Create a list with all the packages already installed4pckgs_installed <-installed.packages()[,1]# Install only the packages needed that are not in your computer yet5for (pckgs_sel in pckgs) {print(paste("Checking if the package", pckgs_sel, "is installed"))if (!(pckgs_sel %in% pckgs_installed)) {install.packages(pckgs_sel, dependencies =TRUE)print(paste("The", pckgs_sel, "was installed")) } else {print(paste("The", pckgs_sel, "is already installed" ))}}# Load the packages6lapply(pckgs, library, character.only =TRUE)
1
Selecione os pacotes necessários;
2
Instale os pacotes (1st way);
3
Ative os pacotes (1st way);
4
Identifique os pacotes já instalados no R (2nd way);
5
Cheque e instale apenas os pacotes que não estão em seu computador (2nd way);
6
Ative os pacotes de interesse (2nd way);
Obtendo e investigando os dados: usando os pacotes GEOBR e CENSOBR
Diferentes são os caminhos para acessar e manipular dados no R. A reconstrução manual da base dentro do próprio ambiente, com a transcrição de dados ainda não digitalizados, é um exemplo. Registre-se, porém, que quanto maior for o volume de dados, mais demorada e suscetível a erros será essa tarefa. Por esse motivo, costuma-se evitar esse tipo de abordagem.
Outra opção consiste em salvar um conjunto de dados já tabulado por alguma instituição (IBGE, IPEA, Fundação SEADE, CEM USP, etc.) em um computador pessoal e abri-lo no ambiente do R. O IBGE, por exemplo, disponibiliza diferentes recursos e plataformas com essa finalidade: i) a seção do site da instituição voltada aos censos demográficos; ii); o seu sistema de recuperação de informações, o SIDRA, ou, iii) o acesso ao servidor do IBGE via FTP.
Por fim, mas sem esgotar o assunto, o acesso a dados pode ser feito por meio de pacotes criados especificamente para esse fim. Com uma vasta gama de casos no R, este é o caminho que será explorado aqui. Mais especificamente, serão utilizados o CENSOBR, que fornece dados cenistários tabulares (tabelas), e o GEOBR, que disponibiliza dados geoespaciais. A partir desses de ambas as bases, os dados de interesse serão integrados, de forma a incorporar a dimensão territorial na análise.
Com vistas a tornar a presente exploração mais facilmente replicável a outros contextos, a seguir dois objetos são criados: i) um para definir a escala na qual a área de interesse está inserida - no presente caso, dado que a região de interesse é a Liberdade, o município de São Paulo será escolhido - e ii) o outro para o ano do censo de interesse. Iniciando a análise para o ano de 2010, com esse tipo de procedimento bastaria mudar duas informações, a escala e o ano, e todo o restante do código será gerado automaticamente, mas agora com novos dados.
Code
# Let's create a list of variables to reuse the code## Select the municipality(ies)' name(s)mun_name ="São Paulo"## Select the census demographic yearcensus_year =2010# Possible years: 1960, 1970, 1980, 1991, 2000, 2010. See: https://ipeagit.github.io/censobr/articles/censobr.html
O próximo passo consiste em descobrir e escolher quais variáveis do censo retratam a questão e/ou o fenômeno a ser analisado (no presente caso, a raça/cor). Para isso, deve-se recorrer ao dicionário de variáveis.
Antes, porém, é importante relembrar que os dados censitários demográficos produzidos pelo IBGE são disponibilizados a partir de dois grandes tipos: os microdados (dados da amostra) e os agregados por setor censitário (dados do universo)2. Ambos os dados podem ser acessados por meio do pacote CENSOBR3, ainda que o foco da presente exploração baseie-se nos microdados, como anteriormente sinalizado.
Assim sendo, conforme ilustra o código a seguir, inicia-se com a escolha do tipo de dado que será analisado (neste caso, os microdados da amostra). Em seguida, o dicionário de variáveis será visitado para a identificação do tema/variáveis de interesse (no presente caso, a questão racial, retratada como cor ou raça).
Code
# Choose the variables## Select the dataset of interest1dataset_sel ="population"# Para ver as possibilidades, digite ?censobr::data_dictionary no console e veja o argumento "dataset". Ali podem ser vistas as bases disponibiizadas pelo pacote ("population", "households", "families", "mortality", "emigration", "tracts")## See the variable dictionary2data_dictionary(year = census_year, dataset = dataset_sel)# Possibilities: 1960, 1970, 1980, 1991, 2000, 2010. See: https://ipeagit.github.io/censobr/articles/censobr.html
1
Defina qual base dos microdados será utilizada;
2
Baixe o dicionário de variáveies da base selecionada;
Observando-se o dicionário de variáveis, algumas variáveis foram escolhidas (ver o quadro a seguir). Primando pela concisão, os critérios para a seleção foram a escala de interesse (V0011) e os limites político-administrativos do dado (V0001 e V0002); a geração da estimativa do número de pessoas (V0010); a possibilidade de ligação dessa base com as demais bases dos microdados (V0300) e, por fim, a inclusão da questão a ser analisada, raça (V0606), a qual se acrescentou o genêro (V0601).
Código das variáveis
Nomenclatura
V0001
Unidade da Federação (UF)
V0002
Cód. do município
V0011
Área de ponderação
V0300
Variável de controle
V0010
Peso amostral
V0606
Raça ou Cor
V0601
Sexo
Code
# Choose the population variables of interest var_cens_pop <-c("V0001", "V0002", "V0011", "V0300", "V0010", "V0606", "V0601")
Escolhidas as variáveis, o passo seguinte consiste em obter os dados propriamente ditos (“baixá-los” para a sessão atual do R). Ao realizar essa tarefa, alguns avisos podem ser gerados. Não se preocupe, porém. A partir da leitura dos avisos, verifica-se que as mensagens geradas não se referem a um erro, mas sim a uma série de orientações padrão.
Registre-se, em tempo, que após realizar todo o procedimento de acesso e manipulação para o ano de 2010, adiante o mesmo caminho será replicado com os dados dos censos de 2000 e 1991.
Nota
Os dados da amostra do censo demográfico brasileiro costumam ser grandes e pesados, o que implica em um uso bastante intenso da memória RAM. Para lidar com esse comportamento do R (alocação dos dados na memória RAM), uma estratégia interessante é adotada pelo CENSOBR: preparar/estruturar o cômputo e gerá-lo apenas quando ele for explicitamente solicitado (mais detalhes podem ser vistos aqui).
Code
# Download and Select the variables of interest from POP MICRODATA, including RACEmicro_pop_orig <-read_population(year = census_year, columns = var_cens_pop) # 1) if the downloading was stopped before finishing, use "censobr::censobr_cache(delete_file = "2000_population_v0.3.0.parquet")" to exclude it from your computer before running the code again; 2) for the 2010 census, the argument 'add_labels = "pt"' transform the categories codes of variabels into its labels.
Code
# Compute the total population for the municipality, weighting area (AP) and household by race## Select the municipality of interest and load the pop data1micro_pop <- micro_pop_orig |>2filter(V0001 =="35"& V0002 =="50308") |>3collect() |># mutate(V0624 = as.numeric(V0624)) |>4clean_names()5glimpse(micro_pop)
1
Selecione a base de dados de interesse e crie um novo objeto para armazenar o resultado das operações a seguir;
2
Filtre os dados, escolhendo apenas os que se referem ao município de São Paulo;
3
“Traga” os dados para a sessão atual do R;
4
Uniformize o nome das variáveis (padrão adotado: letras mínusculas, com o espaço entre as palavras preenchido pelo símbolo “_”), e,
A partir do resultado obtido e da padronização adotada pelas funções do Tidyverse, é possível observar rapidamente a estrutura da tabela (552307 linhas/observações e 7 colunas/variáveis), o tipo de dado presente em cada coluna, bem como os primeiros valores para cada uma das variáveis.
Analisando os dados: um retrato para a escala municipal.
Com os dados em mãos, a investigação propriamente dita sobre o comportamento da questão racial pode ir adiante. Nesse sentido, inicialmente será computada a distribuição da variável raça/cor para todo o município. Em seguida, o mesmo procedimento será realizado, mas dessa vez considerando-se a escala de maior detalhe do dado: a área de ponderação. Nesse momento, procurar-se-á entender como a distribuição da raça/cor se dá em diferentes regiões do território paulistano. Por fim, serão identificadas e analisadas as áreas de ponderação que abrangem a região de interesse - e que serão descobertas mais à frente.
A seguir, inicia-se o cômputo para o município, como um todo. Para facilitar a interpretação, algumas transformações são realizadas na base (conversão de tipos de dados e criação de novas variáveis, por ex.).
Code
# Compute the RACE distribution by MUN1race_by_mun_2010 <- micro_pop |>mutate(v0606 =factor(v0606),raca_cor_nome =factor(case_when( v0606 ==1~"Branca", v0606 ==2~"Preta", v0606 ==3~"Amarela", v0606 ==4~"Parda", v0606 ==5~"Indígena", v0606 ==9~"Ignorado")) 2 ) |>3group_by(v0606, raca_cor_nome) |>4summarise(tot_peop_peso =sum(v0010), tot_peop_orig = dplyr::n()) |>5rename(raca_cor = v0606) |>6ungroup() |>7mutate(prop_race =100* tot_peop_peso/sum(tot_peop_peso))# See the result8race_by_mun_2010
1
Selecione a base e crie um objeto para guardar as informações sobre raça/cor em todo o município de São Paulo;
2
Transforme o tipo da variável raça/cor (de character para fator) e crie uma nova variável (coluna). Neste caso, as categorias de raça/cor são codificadas com nomes (preta, indígena, branca, etc.), e não mais números;
3
Defina cada uma das raças/cores como grupos para as operações a seguir;
4
Compute as estimativas da população (tot_peop_peso) e o número de casos amostrados por grupo criado;
5
Renomeie a variável original de raça/cor (v0606);
6
Desagrupe os dados (caso queira entender o impacto desse passo, acrescente o símbolo de comentário no inicío dessa linha (“#”), indicando para o R que o dado deve continuar agrupado; rode o código e veja o resultado produzido);
7
Compute as proporções de pessoas para cada raça/cor e
8
Observe o resultado (quantidade e proporção de pessoas para cada raça/cor)
Os dados gerados permitem que se construa um primeiro retrato sobre o total de pessoas por raça/cor no município de São Paulo em 2010. A atual forma pode, contudo, ser alvo de melhorias. Assim sendo, propõe-s uma nova tabela para os dados recém-obtidos. Nela, como pode ser visto, existem menos variáveis, os nomes das variáveis são mais intuitivos (facilitando a leitura), os dados foram reordenados - do grupo com mais pessoas para o que possui menos - e ela é esteticamente mais atraente. Tais medidas, facilmente implementadas, ajudam a manter o foco no que realmente importa e facilitam a leitura e compreensão dos dados.
Nota
Tão relevante quanto a geração de dados é a comunicação dos achados - algo que, aos poucos e na medida do possível, será explorado no presente texto. Isso porque, caso a sua publicização não seja adequada, o impacto gerado, na melhor das hipóteses, deixará de atingir toda a sua potencialidade. Ou seja, não desconsidere esse fator!
Code
# Adjust and make a new table 1race_by_mun_2010 |>2select(raca_cor_nome, tot_peop_peso, prop_race) |>3rename("Raça ou cor"= raca_cor_nome, "Total de pessoas"= tot_peop_peso, "Proporção (%)"= prop_race) |>mutate(across(.cols =`Total de pessoas`, .fns = round),4across(.cols =`Proporção (%)`, .fns =~round(., digits =2))) |>5arrange(desc(`Proporção (%)`)) |>6gt()
1
Selecione a base de dados gerada;
2
Escolha apenas as variáveis de interesse;
3
Renomeie as variáveis;
4
Arrendonde os valores referentes ao total de pessoas e à proporção;
5
Ordene os dados da maior proporção de pessoas para a menor, e,
6
Gere uma tabela mais visualmente atrativa;
Raça ou cor
Total de pessoas
Proporção (%)
Branca
6823004
60.63
Parda
3447290
30.63
Preta
717215
6.37
Amarela
250146
2.22
Indígena
12959
0.12
Ignorado
2891
0.03
Outra forma bastante interessante para a visualização de dados e compreensão daquilo que se quer entender baseia-se no uso de gráficos. Para o presente caso, a opção mais apropriada seria o gráfico de barras. E como forma de explorar parte dos elementos que podem compô-lo, optou-se por i) adotar um título, subtítulo e fonte, e, ii) modififcar os valores dos eixos e a cor de fundo. Saliente-se, porém, que o uso de cor fazendo referência às raças ou mesmo o título adotado (mais descritivo e geral) poderiam seguir estratégias distintas e talvez mais interessantes, a depender do contexto e objetivo perseguidos - enfatizando o grupo de interesse, por exemplo4.
Code
# Create a graphic for the race distribution## Parameters to reusetitle_grap ="Distribuição de pessoas por cor ou raça"subtitle_grap ="Município de São Paulo, 2010"data_orig_grap ="IBGE, Censo 2010"# ap_sel <- c(3550308005001, 3550308005007, 3550308005008)## Municipality1race_mun_graph <- race_by_mun_2010 |>2ggplot(aes(x =fct_reorder(raca_cor_nome, tot_peop_peso, .desc = T), y = tot_peop_peso, fill = raca_cor_nome)) +3geom_col(show.legend = F) +geom_text(aes(label =round(tot_peop_peso)),vjust =-0.5,hjust =0.5,size =4,fontface ="bold",# colour = "#3b3938"4 ) +geom_text(aes(label =str_c("(", round(prop_race, 2), "%)")),vjust =1.25,hjust =0.5,5size =3.5) +labs(title = title_grap,subtitle = subtitle_grap,caption = data_orig_grap,# x = "(Cor ou raça)",# y = "(Número de pessoas)"6 ) +7scale_fill_manual(values =c("yellow", "#fee6ce", "lightgrey", "#bf812d", "#8c510a", "#5e3814")) +scale_y_continuous(breaks =c(0, 2000000, 4000000, 6000000),8labels =c("0", "2 Mi", "4 Mi", "6 Mi")) +# scale_fill_viridis_d(direction = 1) +9theme_classic(base_size =14) +theme(axis.ticks.x =element_blank(),# axis.text.x = element_blank(),axis.ticks.y =element_blank(),# axis.text.y = element_blank(),axis.title =element_blank() # element_text(colour = "grey", size = 7.5)) )# Look the graphic10race_mun_graph
1
Defina qual será a base utilizada para a criação do gráfico e crie um objeto para salvar o resultado gerado a seguir;
2
Selecione quais variáveis serão expostas no gráfico (eixos x e y);
3
Escolha o gráfico de barras como opção de representação;
4
Defina a localização dos totais de pessoas nas barras;
5
Defina a localização da proporção de pessoas nas barras;
6
Defina quais serão o título, subtítulo e fonte;
7
Defina cores específicas para cada uma das raças (barras);
8
Defina novos intervalos para o eixo y (total de pessoas);
9
Escolha como o fundo e os elementos dos eixos devem ser visualizados, e,
10
Apresente o gráfico.
A partir da tabela e do gráfico, verifica-se, por exemplo, que cerca de 3/5 (60,6%) da população paulistana se autodeclarou branca em 2010. A população negra (parda + preta), por sua vez, respondeu por 37% de todos os paulistanos e paulistanas. No extremo oposto encontram-se as pessoas com algum tipo ascendência dos povos asiáticos (amarelos) e à população indígena. Presentes em nosso território antes da colonização europeia, os povos originários do Brasil representavam apenas 0,1% dos e das paulistanas em 2010, totalizando quase treze mil pessoas.
Analisando os dados: avançando no entendimento sobre a distribuição da raça/cor nas diferentes partes do território municipal (áreas de ponderação)
De forma a aprofundar o conhecimento sobre a área de interesse aqui tratada (região da Liberdade), a partir desse momento passa-se a explorar a distribuição da raça/cor por área de ponderação. Ao revisitar a temática em uma escala mais detalhada, comparações entre regiões tornam-se possíveis, com novos subsídios e/ou padrões podendo ser revelados (para o município e para a área de interesse).
A seguir, o código gera a distribuição da população por raça/cor para cada uma das áreas de ponderação do município de São Paulo.
Code
# Compute the RACE distribution by APrace_by_ap_2010 <- micro_pop |>mutate(v0606 =factor(v0606),v0011 =factor(v0011) ) |>group_by(v0011, v0606, .drop =FALSE) |>summarise(tot_peop_peso =sum(v0010), tot_peop =n()) |>mutate(prop_race =100*tot_peop_peso/sum(tot_peop_peso),raca_cor_nome =factor(case_when( v0606 ==1~"Branca", v0606 ==2~"Preta", v0606 ==3~"Amarela", v0606 ==4~"Parda", v0606 ==5~"Indígena", v0606 ==9~"Ignorado")) ) |>relocate(ap = v0011, raca_cor = v0606, raca_cor_nome) # Show the resultrace_by_ap_2010
O resultado produzido está no que se costuma chamar de base ou tabela de forma longa. Mais adequada para a manipulação de dados, percebe-se que para cada área de ponderação são apresentadas todas as categorias da variável raça/cor, dispostas verticalmente, bem como os seus valores. Tomando-se como exemplo a primeira área de ponderação, 3550308005001, verifica-se que a primeira linha é destinada à raça branca, a segunda à preta, a terceira à amarela e assim por diante. Essa disposição é, então, retomada quando se inicia a segunda área de ponderação, 3550308005002, com a sétima linha apresentando os dados para a raça branca, a oitava para a raça preta, etc. Tal forma, saliente-se, nem sempre facilita a visualização e o entendimento do que se quer investigar.
Tendo isso em vista, a seguir os mesmos dados serão apresentados a partir da chamada forma ampla ou larga. Como poderá ser visto, dessa vez cada área de ponderação ocupa apenas uma linha da tabela. As categorias da variável raça/cor, por sua vez, são transpostas para as colunas.
Code
# Transpose the data into a wider table 1race_by_ap_2010_wider <- race_by_ap_2010 |>2pivot_wider(id_cols = ap, names_from = raca_cor, values_from =c(tot_peop_peso, prop_race)) |>3set_names("ap", "branca", "preta", "amarela", "parda", "indigena", "ignorado", "branca_prop", "preta_prop", "amarela_prop", 'parda_prop', "indigena_prop", "ignorado_prop") |>4relocate("ap", "branca", "parda", "preta", "amarela", "indigena", "ignorado", "branca_prop", 'parda_prop', "preta_prop", "amarela_prop", "indigena_prop", "ignorado_prop") |>5ungroup() |>6mutate(tot_pop = branca + parda + preta + amarela + indigena + ignorado)# See the first version of the wider table7race_by_ap_2010_wider# Look only to the number of people (absolute values) by AP and race8head(race_by_ap_2010_wider[c(1:7, 14)], n =10) |>mutate(across(.cols =!ap, .fns = round)) |>rename(Branca = branca, Parda = parda, Preta = preta, Amarela = amarela, `Indígena`= indigena, Ignorado = ignorado, Total = tot_pop) |>gt(rowname_col ="ap")# Now consider only the proportion of people (relative values) by AP and race9head(race_by_ap_2010_wider[c(1, 8:14)], n =10) |>rename(`Branca (%)`= branca_prop, `Parda (%)`= parda_prop, `Preta (%)`= preta_prop, `Amarela (%)`= amarela_prop, `Indígena (%)`= indigena_prop, `Ignorado (%)`= ignorado_prop, Total = tot_pop) |>gt(rowname_col ="ap")# write_csv2(race_by_ap_2010_wider, file = here(file.path("2010", "Gerados", "Tabelas", "raca_ap_sp_2010.csv")))
1
Selecione a base e crie um objeto para salvar os dados em formato longo;
2
Transforme as categorias da variável raça/cor, originalmente empilhadas, em colunas;
3
Adote novos nomes (mais intuitivos) para as colunas;
4
Mude a ordem das colunas;
5
Desagrupe os dados;
6
Crie uma coluna e compute a população total das AP (soma de todas as raças mais os casos “ignorado”);
7
Observe os dados dispostos na nova forma e note que a base apresenta tanto os dados absolutos quanto os relativos;
8
Observe os resultados para as dez primeiras áreas de ponderação, considerando apenas o número de pessoas (volume) para cada cor/raça (perceba o arredondamento dos valores praticado), e,
9
Observe os resultados para as dez primeiras áreas de ponderação, mas agora considerando apenas a proporção de pessoas para cada cor/raça.
A partir das últimas tabelas, que apresetam os valores absolutos (número total/volume/montante de pessoas) e relativos (proporção de pessoas), verifica-se uma disposição dos dados mais amigável. Um desafio persiste, porém: o município de São Paulo é composto por 310 áreas de ponderação. Ou seja, a tabela é constituída por 310 linhas, tornando a apreensão do todo difícil.
Em situações desse tipo, com bases de dados extensas, usualmente recorre-se a estratégias para sintetizá-los e explicitar eventuais padrões. Uma delas, inclusive, já foi explorada: o uso de ferramentas baseadas em visualização de dados, como os gráficos. A ela, some-se a geração de medidas síntese de localização, tal qual a famigerada média, e de dispersão, dentre as quais uma das mais conhecidas é o desvio padrão.
A seguir, dois tipos de gráficos (“pontos” e “boxplot + violino”) e uma tabela (composta por medidas de resumo) serão apresentados. Mais do que replicar as mesmas informações em formatos distintos, o que se espera é que eles se complementem e possibilitem uma leitura mais rica e acurada.
Iniciando a exploração com os gráficos, forma mais intuitiva, almeja-se verificar se alguns indícios ou padrões revelam-se a partir de uma análise visual. A partir das intuições encontradas e/ou questionamentos levantados (lembre-se: os questionamentos são a base da ciência!), em um segundo momento serão computados elementos “mais precisos” (estatísticas) para uma melhor descrição e caracterização da distribuição espacial da raça/cor, agregados em formato de tabela.
Code
# Create a graphic representing the race distribution with a dot plot (here, some noise is added)graf_race_ap_2010_pnt0 <- race_by_ap_2010 |>ggplot(aes(x =fct_rev(fct_reorder(raca_cor_nome, tot_peop_peso, median)), y = tot_peop_peso)) +geom_point(alpha =0.4, shape =1) +labs(x =NULL,y =NULL) +theme_classic(base_size =14) +theme(# axis.ticks.x = element_blank(),axis.ticks.y =element_blank()) +coord_flip()# Create a graphic representing the race distribution with a dot plot1graf_race_ap_2010_pnt <- race_by_ap_2010 |>2ggplot(aes(x =fct_rev(fct_reorder(raca_cor_nome, tot_peop_peso, median)), y = tot_peop_peso)) +3geom_point(position ='jitter', alpha =0.4, shape =1) +labs(x =NULL,4y =NULL) +5theme_classic(base_size =14) +theme(# axis.ticks.x = element_blank(),axis.ticks.y =element_blank()) +6coord_flip()# Create a graphic representing the race distribution with a violin and boxplotgraf_race_ap_2010_res <- race_by_ap_2010 |>ggplot(aes(x =fct_rev(fct_reorder(raca_cor_nome, tot_peop_peso, median)), y = tot_peop_peso)) +geom_boxplot() +geom_violin(scale ="width", fill =NA, color ="darkorange", alpha =0.7) +labs(x =NULL,y =NULL) +theme_classic(base_size =14) +theme(# axis.ticks.x = element_blank(),axis.ticks.y =element_blank()) +coord_flip()# Plot and compare both graphics7(graf_race_ap_2010_pnt0 / graf_race_ap_2010_pnt / graf_race_ap_2010_res)
1
Selecione a base de dados e crie um objeto para salvar o gráfico;
2
Defina quais serão as variáveis que aparecerão no gráfico;
3
Escolha o tipo de gráfico/representação dos dados. Note: nos dois primeiros casos, gera-se um gráfico de pontos, com os dados do segundo levemente deslocados. Já no segundo apresenta-se uma sobreposição entre o gráfico de violino e boxplot;
4
Exclua o nome dos eixos dos gráficos;
5
Defina alguns elementos visuais do gráfico, como o tamanho das letras, a cor do fundo e a exclusão dos pequenos traços que ligam os valores aos eixos;
6
Inverta o eixo dos gráficos, e,
7
Defina a ordem em que os gráficos serão dispostos.
Como pode ser visto, três gráficos são apresentados. Note-se, contudo, que tanto o primeiro quanto o segundo tratam de um mesmo tipo de representação (gráfico de pontos). Neles, os pontos indicam qual é a população total de cada uma das áreas de ponderação por raça/cor - a diferença, aqui explorada para fins didáticos, reside no fato do segundo gráfico apresentar dados ligeiramente deslocados de seu valor real, uma técnica usada para facilitar a análise e a apreensão de padrões.
Obervando-se a localização dos pontos, verifica-se, por exemplo, que enquanto as populações preta, indígena e amarela apresentam valores mais concentrados (maior número de pontos próximos e/ou sobrepostos, reforçando a cor preta), no caso das populações pardas e branca o total de pessoas nas áreas de ponderação está mais disperso (há uma maior variabilidade). Grosso modo, poder-se-ia dizer que o tamanho das populações preta, indígena e amarela, por área de ponderação, é mais parecido do que o encontrado para as populações branca e parda.
Considerando-se essa mesma separação, é seguro afirmar que todas as áreas de ponderação do município de São Paulo (ponto preto) possuem menos de 10.000 habitantes pretos, indígenas ou amarelos - limiar ultrapassado pelos residentes brancos e pardos em várias áreas de ponderaçao. Também é possível notar que, diferentemente de todas as outras populações, as áreas de ponderação com o menor número de pessoas brancas somam cerca de 10.000 pessoas - exceção feita a dois casos.
O segundo gráfico, composto pela sobreposição entre o gráfico de violino (linha laranja) e o boxplot , busca representar a distribuição da população, por raça/cor e áreas de ponderação, de outra forma. Iniciando-se a leitura pelo boxplot, destaque-se que alguns elementos dessa representação costumam ser sempre observados. Um deles é a sua caixa, que perfaz a metade central de todo o conjunto dos dados. Com isso, é possível estimar, por exemplo, que metade da população branca varia entre 16 e 26 mil pessoas, considerando-se a sua distribuição por área de ponderação. Já no caso da população parda esses valores parecem variar entre 5.000 e 15.000 pessoas (não se preocupe com a precisão nesse momento, pois os números corretos serão observados na tabela produzida mais adiante).
O boxplot fornece, ainda, ao menos duas outras informações interessantes. A primeira diz respeito à linha vertical central da caixa, que indica onde se encontra a mediana. Ordenando-se os totais das populações do menor para o maior valor, a mediana é o valor que divide o conjunto de dados ao meio5. No caso da população preta, por exemplo, esse valor parece estar próximo a 2.500 pessoas.
A outra informação de interesse está relacionada aos pontos que aparecem para algumas raças/cores. Neste caso, eles indicam as áreas de ponderação cuja população é muito diferente de todo o restante - esses casos são chamados de pontos discrepantes ou outliers. Percebe-se, por exemplo, que a raça amarela possui algumas áreas de ponderação com uma população muito maior do que o comportamento geral dessa raça no município. Já no extremo oposto encontra-se a populaçao preta, que não apresenta nenhuma área de ponderação que foge do comportamento geral dessa raça/cor.
Complementando os achados do boxplot, novos elementos obtidos por meio do gráfico de violino podem ser acrescentados. Ao representar de forma mais contínua a distribuição das populações por raça/cor e área de ponderação, é possível notar, por exemplo, que a população parda apresenta dois pequenos picos, um logo abaixo de 5.000 pessoas e outro em torno de 14.000 pessoas. As populações preta e branca, por sua vez, parecem apresentar um único pico. Com um olhar um pouco mais treinado, também é possível notar uma ligeira concentração de casos antes da mediana para essas raças/cores - compare o tamanho das caudas do gráfico antes e depois da linha da mediana.
De forma a tornar mais precisos os indícios, intuições e questões gerados a partir da visualização dos dados e avançar na busca de novos achados, a seguir serão computadas algumas estatísticas para cada uma das raças. Os resultados, por sua vez, são agrupados em uma mesma tabela.
Code
# Compute some metrics to describe the data## Compute the measures by race1branca_mtrc <-summary(race_by_ap_2010_wider$branca)parda_mtrc <-summary(race_by_ap_2010_wider$parda)preta_mtrc <-summary(race_by_ap_2010_wider$preta)amarela_mtrc <-summary(race_by_ap_2010_wider$amarela)indigena_mtrc <-summary(race_by_ap_2010_wider$indigena)ignorado_mtrc <-summary(race_by_ap_2010_wider$ignorado)## Create a table with all race metrics2tab_race_metrcs_ap <-bind_rows(branca_mtrc, parda_mtrc, preta_mtrc, amarela_mtrc, indigena_mtrc, ignorado_mtrc) |>3as.data.frame() |>mutate(raca_cor =c("Branca", "Parda", "Preta", "Amarela", "Indigena", "Ignorado"),4across(.cols =!raca_cor, .fns = round)) |>5relocate(raca_cor) |>6set_names("Raça ou cor", "Menor valor", "1o. Quartil", "Mediana", "Média", "3o. Quartil", "Maior valor")tab_race_metrcs_ap |>7gt(rowname_col ="Raça ou cor")
1
Compute algumas métricas para cada uma das raças/cores;
2
Junte todas as métricas calculadas (“colando” as linhas);
3
Transforme a junção anterior em um data.frame (“tabela”);
4
Acrescente uma variável para a raça/cor e arredonde os valores da população;
5
Coloque a variável raça/cor na primeira posição da base, e,
6
Defina nomes mais intuitivos para as variáveis, e,
7
Crie uma tabela mais visualemente atrativa.|
Menor valor
1o. Quartil
Mediana
Média
3o. Quartil
Maior valor
Branca
4160
17078
21362
22010
26572
42376
Parda
720
5276
11051
11120
15784
30592
Preta
82
1274
2264
2314
3186
6208
Amarela
19
238
494
807
941
6940
Indigena
0
0
22
42
48
1005
Ignorado
0
0
0
9
0
1231
A partir dos valores da tabela, verifica-se que as percepções obtidas por meio dos gráficos é corroborada pelos números. Um dos achados obtidos visualmente indicava uma maior concentração dos valores das populações preta, amarela e indígena por área de ponderação - levando, a grosso modo, à noção de que a distribuição dessas raças ao longo do território era mais parecido (ou menos diferente) do que o encontrado para as raças brancas e parda. Recorrendo-se ao Intervalo Interquaril (IQR) para quantificar esse comportamento6, constata-se que a diferença das populações por área de ponderação para as raças branca e preta é de 9.494 e 10.508 pessoas, respectivamente. Por sua vez, ao se considerar as populações preta, amarela e indígena, essa diferença é de 1.912, 703 e 48 pessoas. Ou seja, mesmo considerando-se a diferença entre a população branca (menor valor do grupo mais disperso, de acordo com o IQR) e a população preta (maior valor do grupo mais concentrado), a dispersão ou variabilidade é cinco vezes maior a favor da raça branca (9.494 pessoas brancas/1.912 pessoas pretas).
Observando-se as menores quantidades de pessoas por raça/cor presentes nas áreas de ponderação (coluna “Menor valor” da tabela), percebe-se que enquanto existe ao menos uma área de ponderação que não possui indígenas - valor que salta para ao menos 25% das áreas de ponderação, dado que o valor do 1º quartil é 07 -, o menor número de pessoas brancas em uma área de ponderação no município é de 4.160. Esse valor, aliás, é maior do que o encontrado em ao menos 75% de todas as áreas de ponderação para as raças/cores preta, amarela e indígena (observe e compare os dados a partir da coluna do 3º quartil).
Em sentido oposto, ao se considerarem as maiores quantidades de pessoas por raça/cor e área de ponderação (coluna “Maior valor”), agora é possível mensurar e identificar as áreas que possuem as maiores populações preta (6.208 pessoas), amarela (6.940) e indígena (1.005). Dado que a simples comparação desse valor com o do 3º quartil para cada uma dessas raças/cores indica uma diferença não desprezível, pode-se aventar ou suspeitar que algo ocorreu/ocorre nessas porções do território, fomentando essa concentração espacial.
Operando-se de forma similar, verifica-se que as estatísticas da tabela especificam as medidas anteriormente obtidas por meio dos gráficos. Dessa forma, as aproximações geradas para os percentis 25º e 75º (medidas/linhas limites da caixa do boxplot), bem como para o 50º (mediana, representanda pela linha dentro da caixa), agora são mensuradas e localizadas de forma mais precisa. No caso da população preta, por exemplo, o primeiro, o segundo (mediana) e o terceiro quartis correspondem a 1.274, 2.264 e 3.186 pessoas. Por sua vez, essas mesmas medidas para a população parda perfazem 5.276, 11.051 e 11.120 pessoas.
Para finalizar essa etapa de “contextualização regional”, duas novas estratégias serão rapidamente exploradas. Enquanto a primeira está baseada no tamanho das áreas de ponderação, como um todo (ou seja, considerando todas as raças/cores), a segunda abordará a questão a partir do tamanho da população negra (pessoas pardas + pessoas pretas).
O código a seguir fornece subsísios para a análise das áreas de ponderação (AP) mais populosas. O objetivo será compreender a composição por raça/cor para as cinco áreas com os maiores números de residentes - o número 5 foi escolhido para tornar a análise mais paupável e inteligível a partir dos dados brutos. Note-se, ainda, que um ranqueamento foi criado para auxiliar a leitura.
Selecione a base de interesse e crie um objeto para salvar os resultados;
2
Selecione apenas as variáveis que apresentam os totais populacionais por raça/cor (todas aquelas que não terminavam com “_prop”);
3
Ranqueie, considerando a população total, as áreas de ponderação (AP) para cada uma das raça/cores ;
4
Adote nomes mais intuitivos para as variáveis;
5
Ordene as AP em função do tamanho de suas populações totais;
6
Selecione as cinco primeiras AP (mais populosas);
7
Defina nomes de variáveis mais intuitivas;
8
Gere uma tabela mais visualmente atrativa, e,
9
Repita o mesmo procedimento, mas agora considerando as proporções populacionais por raça/cor e área de ponderação.
AP
Branca
Parda
Preta
Amarela
Indígena
Ignorado
Total
Branca (Rank)
Parda (Rank)
Preta (Rank)
Amarela (Rank)
Indígena (Rank)
Total (Rank)
3550308005259
23107
28449
5200
233
0
0
56989
127
2
5
236
201
1
3550308005189
24431
24757
6208
219
124
0
55739
99
3
1
242
22
2
3550308005280
25903
23058
4934
157
39
1231
55321
86
10
8
273
100
3
3550308005135
25197
24448
4172
206
101
0
54124
91
4
24
246
32
4
3550308005237
28194
20455
3783
856
79
0
53366
53
33
44
93
43
5
AP
Branca %
Parda %
Preta %
Amarela %
Indígena %
Ignorado %
Total
Branca % (Rank)
Parda % (Rank)
Preta % (Rank)
Amarela % (Rank)
Indígena % (Rank)
Total % (Rank)
3550308005259
40.55
49.92
9.12
0.41
0.00
0.00
56989
294
21
52
273
201
1
3550308005189
43.83
44.42
11.14
0.39
0.22
0.00
55739
265
62
14
276
44
2
3550308005280
46.82
41.68
8.92
0.28
0.07
2.22
55321
237
84
57
298
139
3
3550308005135
46.55
45.17
7.71
0.38
0.19
0.00
54124
242
58
92
280
58
4
3550308005237
52.83
38.33
7.09
1.60
0.15
0.00
53366
199
111
119
132
71
5
A partir dos dados gerados, verifica-se que as cinco áreas de ponderação (AP) mais populosas do município de São Paulo variam de 56989 a 53366 pessoas (com uma média de 55107.8 pessoas). E tal qual ocorre no município, as raças branca e parda concentram os maiores quantitativos de pessoas (cerca de 61 e 31) nessas áreas, sendo seguidas mais de longe pela pessoas pretas, amarelas e indígenas.
Ressalte-se, contudo, que a distância encontrada nesses casos é bem menor. Computando-se duas medidas de tendência central, constata-se que os totais médio e mediano de pessoas brancas dessas cinco AP são de 25366 e 25197. Já no caso das pessoas pardas, eles correspondem a 24233 e 25197.
Também é possível verificar que nas duas AP com o maior número de residentes do município (3550308005259 e 3550308005189) ocorre uma inversão entre as raças/cores branca e parda. Totalizando 49,9% (28.449 pessoas) e 44,4% (24.747), a população parda ali presente supera a branca - a leitura espacial a seguir indicará que essas duas AP estão localizadas nos distritos do Lajeado, extremo leste do município, e da Brasilândia, na Zona Norte. Mais: caso se considere a população negra (preta + parda), das cinco AP mais populosas, apenas a 3550308005237 possui mais residentes brancos - com 53% de brancos e 45% de negros, essa área está localizada no distrito do Campo Limpo. Para as quatro AP restantes, os números da população negra variam de 51% do total a 59% (27.992 a 33.649 pessoas, respectivamente).
Feitos esses breves comentários, passa-se, agora, a alguns breves comentários baseados no ranqueamento das raças/cores para as cinco AP analisadas. Antes, contudo, é importante reforçar que o ordenamento e a classificação foram realizados do maior valor (que ocupa a posição 1) para o menor (que ocupa a posição 310). Com isso, torna-se possível “olhar para dentro” de cada raça/cor e entender a sua distribuição territorial específica.
Consideranço-se apenas os totais populacionais (valores absolutos), verifica-se, de forma geral, que as cinco AP mais populosas também apresentam grandes contingentes de pessoas pardas e negras . Observa-se, por exemplo, que quatro das cinco AP mais populosas do município estão entre as 10 AP mais pardas do município (posições 2, 3, 4 e 10). No caso da população preta, o mesmo ocorre para três dos cinco casos analisados (posições 1, 8 e 5). Apenas para efeito de comparação, a AP que possui o maior número de pessoas brancas (28.194) dentre as 5 AP mais populosas do município ocupa apenas a posição 51 no ranking de AP da raça/cor branca.
A seguir, as cinco AP analisadas são espacializadas e inseridas dentro dos seus respectivos distritos (limites em roxo e linha preta). Localizadas em diferentes partes do território (zonas Leste, Norte e Sul), percebe-se com relativa facilidade um traço comum: todas se encontram em regiões periféricas do município. Note: para além da legenda, localizada no canto direito superior do “mapa”, no canto inferior direito aparece a identificação dessas AP novamente. Esse “botão translúcido”, ao ser clicado, leva a um zoom da área escolhida no mapa. Para retornar ao zoom inicial, clique no botão no canto inferior esquerdo (Zoom full).
Code
# Select the 1st five AP with the highest population## Get the AP spatial limitsap_mun_sp <-read_weighting_area(code_weighting =3550308, year =2010, simplified = F)## Find out the code of the 1st five AP with the highest population from the aspatial data settop5_ap_abs <- race_by_ap_2010_wider_pos_abs |>slice_head(n =5) # |> pull(ap)## Filter the 1st 5 AP spatial limits of interest ap_top5_pop_geo <- ap_mun_sp |>select(code_weighting, name_muni) |>right_join(top5_ap_abs, join_by(code_weighting == ap)) |>relocate(name_muni) |>arrange(desc(total))ap_top5_pop_geo_pts <- ap_top5_pop_geo |>st_centroid()# Get the district spatial limits for SP municdistrito_mun_sp <-read_neighborhood(year =2010, simplified = F) |>filter(code_muni ==3550308) |>select(abbrev_state, name_muni, code_district, name_district)# See both AP selected and District data together in the space## See the color pallets availabledisplay.brewer.all(n =NULL, type ="all", select =NULL, exact.n =TRUE, colorblindFriendly =TRUE)
Code
## Create a map to show the AP limitsmap_top5_ap_pop_lim <-mapview(distrito_mun_sp, zcol ="name_district", color ="gray35", col.regions ="royalblue", alpha.regions =0.4, legend =FALSE) +mapview(ap_top5_pop_geo, zcol ="code_weighting", lwd =2, burst = T, legend =FALSE) ## Create a map to show the AP centroids/pointsmap_top5_ap_pop_pts <-mapview(distrito_mun_sp, zcol ="name_district", color ="gray35", col.regions ="royalblue", alpha.regions =0.4, legend =FALSE) +mapview(ap_top5_pop_geo_pts, zcol ="total", cex ="total", layer.name ="Pop. (total)")# col.regions # col.regions # col.regions = rev(brewer.pal(5, "YlOrRd")))## Show both mapsleafsync::sync(map_top5_ap_pop_lim, map_top5_ap_pop_pts, ncol =2)
Para o desenvolvimento da segunda estratégia, propõe-se uma leitura mais integrada entre os dados e sua distribuição espacial. Mais do que formalizar ou representar de outra forma os achados, agora a espacialização contribuirá mais ativamente para a produção de subsídios e achados.
Nesse sentido, a seguir serão computados e ordenados os totais e as proporções da população negra por área de ponderação, com destaque para as cinco maiores áreas/populações. Note: ainda que possa se basear no ranqueamento realizado anteriormente, de forma a explorar a construção de códigos um caminho distinto é proposto.
Code
# Select the 5 weighting areas (AP) with the highest black population (absolute values)## Compute the total black population for all 310 AP1tab_black_ap_abs <- race_by_ap_2010_wider_pos_abs |>mutate(negra = parda + preta,2negra_rank =min_rank(desc(negra))) |>3relocate(negra, .after = preta) |>relocate(negra_rank, .after = preta_rank) |>4arrange(desc(negra))## Select only the 5 AP with most Black population tab_black_ap5_abs <- tab_black_ap_abs |>5head(5)## Create a more attractive tabletab_black_ap5_abs |>6select(!ends_with("_rank")) |>7set_names("AP", "Branca", "Parda", "Preta", "Negra", "Amarela", "Indígena", "Ignorado", "Total") |># set_names("AP", "Branca", "Parda", "Preta", "Negra", "Amarela", "Indígena", "Ignorado", "Total", "Branca (Rank)", "Parda (Rank)", "Preta (Rank)", "Amarela (Rank)", "Indígena (Rank)", "Total (Rank)") |> 8gt()# Select the 5 weighting areas with the highest proportion of black people (relative values)## Compute the total black population for all 310 AP9tab_black_ap_prop <- race_by_ap_2010_wider_pos_prop |>mutate(negra_prop = parda_prop + preta_prop,negra_prop_rank =min_rank(desc(negra_prop))) |>relocate(negra_prop, .after = preta_prop) |>relocate(negra_prop_rank, .after = preta_prop_rank) |>arrange(desc(negra_prop)) tab_black_ap5_prop <- tab_black_ap_prop |>head(5)# Create a more attractive tabletab_black_ap5_prop |>select(!ends_with("_rank")) |>mutate(across(!c(ap, total), .fns =~round(x = ., digits =2))) |>set_names("AP", "Branca (%)", "Parda (%)", "Preta (%)", "Negra (%)", "Amarela (%)", "Indígena (%)", "Ignorado (%)", "Total") |># set_names("AP", "Branca", "Parda", "Preta", "Negra", "Amarela", "Indígena", "Ignorado", "Total", "Branca (Rank)", "Parda (Rank)", "Preta (Rank)", "Amarela (Rank)", "Indígena (Rank)", "Total (Rank)") |> gt()
1
Selecione a base de interesse e crie um objeto para salvar os resultados;
2
Adicione duas novas variáveis, uma para a contagem da população negra (var negra) e a outra para o seu ranqueamento (var. negra_rank);
3
Desloque as variáveis criadas;
4
Ordene a base em função da população total negra de forma decrescente (do maior para o menor valor);
5
Selecione as cinco primeiras AP (cinco maiores populações negras);
6
Exclua as variáveis que tratam do ranqueamento para a criação de uma tabela mais limpa;
7
Defina nomes de variáveis mais intuitivas;
8
Gere uma tabela mais visualmente atrativa, e,
9
Repita o mesmo procedimento, mas agora considerando as proporções populacionais por raça/cor e área de ponderação.
AP
Branca
Parda
Preta
Negra
Amarela
Indígena
Ignorado
Total
3550308005259
23107
28449
5200
33649
233
0
0
56989
3550308005175
16957
30592
2855
33447
332
0
0
50736
3550308005189
24431
24757
6208
30965
219
124
0
55739
3550308005194
18399
24363
4318
28681
335
16
0
47431
3550308005135
25197
24448
4172
28620
206
101
0
54124
AP
Branca (%)
Parda (%)
Preta (%)
Negra (%)
Amarela (%)
Indígena (%)
Ignorado (%)
Total
3550308005290
30.40
59.56
9.72
69.28
0.31
0.00
0
32966
3550308005175
33.42
60.30
5.63
65.92
0.66
0.00
0
50736
3550308005289
33.79
57.05
8.60
65.65
0.37
0.19
0
30152
3550308005281
34.16
57.74
7.31
65.05
0.79
0.00
0
29088
3550308005292
35.05
55.22
9.17
64.39
0.51
0.05
0
43382
Para complementar a leitura a partir dos dados totais e proporcionais da população negra no município de São Paulo, a seguir eles são espacializados.
Code
# Cross the district and AP layers ap_mun_sp_with_dstrc <- ap_mun_sp |>st_centroid() |>st_intersection(distrito_mun_sp[c("name_district")]) |>mutate(name_district =factor(name_district)) |>arrange(code_weighting) |>st_drop_geometry()# Add the district info into the AP limitsap_mun_sp_with_dstrc <- ap_mun_sp |>left_join(ap_mun_sp_with_dstrc[c("code_weighting", "name_district")], join_by(code_weighting))# Join the AP limits (geospatial) with pop data by AP (aspatial)ap_pop_black_abs_geo <- ap_mun_sp_with_dstrc |>select(name_muni, code_weighting, name_district) |>right_join(tab_black_ap_abs, join_by(code_weighting == ap)) |>arrange(desc(negra))# Select the 5 highest black population by APap_top5_pop_black_abs_geo <- ap_pop_black_abs_geo |>head(5)# Create the centroids of the 5 highest black population by APap_top5_pop_black_abs_geo_pts <- ap_top5_pop_black_abs_geo |>st_centroid()# Map the black population by AP and show the 5 biggest pop/area## Fill all the AP with black populationmap_ap_pop_black_lim <-mapview(ap_pop_black_abs_geo, zcol ="negra", col.regions =brewer.pal(310, "YlOrRd"), lwd =0.15, layer.name ="Pop. (Total)")## Map the five AP with the highest Black populationmap_top_5_ap_pop_black_pts <-mapview(ap_top5_pop_black_abs_geo_pts, zcol ="negra", cex ="negra",color ="grey25",alpha.regions =0, lwd =2,layer.name ="Pop. (5 mais)", legend = F)## Map the SP's district limitsmap_distrito_mun_sp_lim <-mapview(distrito_mun_sp, zcol ="name_district", alpha.regions =0, lwd =0.3, legend =FALSE)## Join the three layers into a unique geospatial representationmap_black_abs_all <- map_distrito_mun_sp_lim + map_ap_pop_black_lim + map_top_5_ap_pop_black_pts# Join the AP limits (geospatial) with pop data by AP (aspatial)ap_pop_black_prop_geo <- ap_mun_sp |>select(name_muni, ap = code_weighting) |>right_join(tab_black_ap_prop, join_by(ap)) |>mutate(across(.cols =!c("name_muni", "ap", "geom"), .fns =~round(x = ., digits =2))) |>arrange(desc(negra_prop))# Select the 5 highest black population proportions by APap_top5_pop_black_prop_geo <- ap_pop_black_prop_geo |>head(5)# Create the centroids of the 5 highest black population proportions by APap_top5_pop_black_prop_geo_pts <- ap_top5_pop_black_prop_geo |>st_centroid()# Map the black population proportion by AP and show the 5 biggest pop/area## Fill all the AP with black populationmap_ap_pop_black_prop_lim <-mapview(ap_pop_black_prop_geo, zcol ="negra_prop", col.regions =brewer.pal(310, "YlOrRd"), lwd =0.15, layer.name ="Pop. (%)")## Map the five AP with the highest Black population proportionsmap_top_5_ap_pop_black_prop_pts <-mapview(ap_top5_pop_black_prop_geo_pts, zcol ="negra_prop", cex ="negra_prop",color ="black",alpha.regions =0, lwd =2,layer.name ="Pop. (% 5 most)", legend = F)## Join the three layers into a unique geospatial representationmap_black_prop_all <- map_distrito_mun_sp_lim + map_ap_pop_black_prop_lim + map_top_5_ap_pop_black_prop_pts# Show both maps side by sideleafsync::sync(map_black_abs_all, map_black_prop_all)
Como pode ser visto, o recurso de visualização espacial produzido apresenta dois mapas sincronizados. Enquanto à esquerda é possível ver a classificação das áreas de ponderação (AP) em função dos totais da população negra residente, à direita a classifição baseia-se nas proporções da população negra residente nas AP. Note-se, ainda, que as linhas cinzas representam os limites das AP, enquanto as linhas pretas expõem os limites dos distritos municipais.
Analisando os dados: da identificação à caracterização da região de interesse
Conhecida a distribuição da questão racial para o município de São Paulo, como um todo, bem como entre regiões, o próximo passo consiste em observar a distribuição da questão racial em nossa área de interesse (região da Liberdade). O primeiro passo consiste em identificar quais são as áres de ponderação que abrangem a região. Recorrendo a um mapa interativo para essa finalidade, o objetivo será identificar, a partir da navegação espacial, quais são os códigos das áreas de ponderação qu recobrem a área de interesse.
Code
# Download the São Paulo weighting area limits 1ap_mun_sp <-read_weighting_area(code_weighting =3550308, year =2010)
1
Baixe os limites das áreas de ponderação, definindo o município e o ano;
Code
# Download the São Paulo district limits 2distrito_mun_sp <-read_neighborhood(year =2010) |>filter(code_muni ==3550308) |>select(abbrev_state, name_muni, code_district, name_district)
2
Baixe os limites dos distritos, definindo o município, o ano e as variáveis de interesse, e,
Code
# Plot the weighting areas and district limits3mapview(ap_mun_sp, zcol ="code_weighting", legend =FALSE) +mapview(distrito_mun_sp, zcol ="name_district", alpha.regions =0, legend =FALSE)
3
Plote os limites de ambos os dados.
Como pode ser visto, o recurso gerado possibilita não só a navegação digital pelo território - com o deslocamento pelas áreas da cidade e o uso do zoom -, mas também permite escolher a imagem de fundo e as camadas geoespaciais (áreas de ponderação e/ou distritos) a serem visualizadas. Para isso, basta clicar no botão com o desenho de retângulos empilhados no lado esquerdo superior da janela e realizar as escolhas. Note: os vazios e/ou a superposição entre polígonos da mesma camada são resultado apenas da opção para deixar a visualização mais leve. No dado original, contudo, eles não existem (em linguagem mais técnica, não há problemas de topologia).
A partir da interação com o mapa digital, verifica-se que três são as áreas de ponderação (AP) de interesse, com duas pertencendo ao distrito da Liberdade (3550308005007 e 3550308005008) e a outra ao distrito da Sé (3550308005001).
Footnotes
Ainda que alguns dos principais elementos associados à exploração e análise introdutória de dados sejam abordados, não se pretende esgotar todos os elementos que venham a ser revelados. Longe de uma análise extensiva, o que se busca é construir uma lógica/estrutura para a exploração do fenômeno e/ou processo de interesse.↩︎
Ainda que sejam mais usalmente utilizados, alguns dados censitários também são disponibilizados em outros formatos, como as grades estatísticas(https://mapasinterativos.ibge.gov.br/grade2022/default.html).↩︎
A discussão sobre visualização de dados e Storytelling com dados é vasta e não será aqui abordada de forma mais profunda. Uma referência bastante conhecida nesse campo é o livro de Cole N. Knaflic, Storytelling com dados.↩︎
A mediana, diferentemente da média, é muito menos influenciada pela existência de valores discrepantes (outliers), motivo pelo qual é considerada uma medida de tendência central (ou, de forma mais ampla, medida de localização) robusta.↩︎
o IQR é uma medida de dispersão robusta que computa a diferença entre os valores do primeiro e terceiro quartis dos dados.↩︎
Observando-se a tabela com os dados brutos, nota-se que 110, das 310 áreas de ponderação do município de São Paulo, não possuem indígenas residentes (cerca de 35%).↩︎
Source Code
---title: "Raça ou cor em São Paulo - uma leitura a partir dos microdados censitários"description: "Post description for first post"author: "Núcleo de Dados"date: "1/05/2025"image: "cover.jpg"categories: - Spatial distribution - Raceformat: html: code-overflow: wrap code-fold: true code-tools: trueeditor_options: chunk_output_type: console output: falsewarning: falseengine: knitr---```{r}#| label: options_all_doc#| echo: falseknitr::opts_chunk$set(options(scipen =999, digits =5))```# IntroO presente texto explorará brevemente como acessar e manipular alguns dados sobre a questão racial na região central do município de São Paulo. Mais especificamente, o foco recairá sobre a distribuição espacial da população negra residente na região da Liberdade ao longo do tempo.Para isso, dentre as diferentes bases disponíveis, optou-se por utilizar os dados do [censo demográfico brasileiro](https://www.ibge.gov.br/estatisticas/sociais/trabalho/22827-censo-demografico-2022.html?edicao=41852&t=series-historicas), produzidos e disponibilizados pelo [IBGE](https://www.ibge.gov.br). Tal escolha reside na possibilidade de:- Replicar a análise para diferentes partes do território brasileiro (reprodutibilidade);- Realizar o resgate histórico da temática (cobertura temporal) e- Observar a distribuição do fenômeno espacial (cobertura espacial).A análise proposta fará uso dos microdados censitários. Para uma versão similar baseada nos setores censitários, veja essa outra postagem ([**CRIAR LINK**]{.underline}). Por fim, uma análise integrando ambos os dados, microdados e dados agregados por setor censitário, pode ser vista aqui ([**CRIAR LINK**]{.underline}).Antes da exploração proposta, vale mencionar que dois pilares conduzem a análise proposta: i) a busca por uma construção de caráter mais didático e não necessariamente extensiva[^1], e, ii) o uso das chamadas boas práticas para a manipulação de dados. Sem negar a importância da eficiência que as consultas e códigos devem perseguir, privilegia-se uma construção mais gradual, incremental e transparente - tarefa em muito facilitada pela concepção e ferramentas que compõem o [Tidyverse](https://www.tidyverse.org/). Ressalte-se, ainda, que um dos horizontes que guiam o presente esforço é o da [Ciência Aberta](https://pt.wikipedia.org/wiki/Ci%C3%AAncia_aberta).[^1]: Ainda que alguns dos principais elementos associados à exploração e análise introdutória de dados sejam abordados, não se pretende esgotar todos os elementos que venham a ser revelados. Longe de uma análise extensiva, o que se busca é construir uma lógica/estrutura para a exploração do fenômeno e/ou processo de interesse.## Colocando a mão na massa: preparando o ambienteUma prática bastante usual ao escrever códigos no R consiste em "declarar/ativar" os pacotes (de funções) no início do *script* - por vezes isso também ocorre com as variáveis que serão utilizadas ao longo do percurso. Ainda que não seja obrigatória, essa prática permite que as funções sejam utilizadas sem que se explicite o nome do pacote (no R, para declarar o pacote e uma de suas funções segue-se a seguinte forma: *pacote::função*).A seguir, duas formas para instalar e ativar os pacotes necessários são apresentadas. Gerando o mesmo resultado (ativação dos pacotes), a diferença entre a primeira forma (1st Way) e a segunda (2nd Way) é que na última o código checa os pacotes presentes no ambiente local/computador do usuário e apenas instala os que ainda não foram baixados. Já no primeiro caso, mesmo que o pacote já esteja instalado, o comando baixará novamente o seu conteúdo e o reinstalará. Note: para tornar mais claro o que está ocorrendo no segundo caminho de instalação, optou-se por inserir mensagens indicando se o pacote já estava instalado ou não (graças ao uso do comando *print("mensagem_a_ser_exibida")*). Observe, ainda, que o símbolo ***\#*** é utilizado para a inserção de comentários no código, algo tido como uma boa prática. Ou seja, sempre que se fizer uso desse recurso, o conteúdo que vier imediatamente após ele será "ignorado"::: callout-note## NotaO uso de comentários proporciona uma maior inteligibilidade do código e conversa diretamente com a possibilidade de reprodutibilidade do trabalho. Para exemplificar o ponto, pense que você e/ou outras pessoas podem revisitar o código no futuro e alguns detalhes podem não estar mais tão claros.:::```{r}#| label: load_packages#| message: false#| output: false# Save all the packages needed inside an object ("folder")pckgs <-c("tidyverse", "sf", "here", "janitor", "arrow", "censobr", "geobr", "sidrar", "gt", "devtools", "mapview", "terra", "patchwork", "RColorBrewer", "leafsync") # <1># 1st way ## Install all the packages previously selected# install.packages(pckgs, dependencies = TRUE) # <2>## Load the packages. This make all the packages functionalities available # lapply(pckgs, library, character.only = TRUE) # <3># 2nd way## Create a list with all the packages already installedpckgs_installed <-installed.packages()[,1] # <4># Install only the packages needed that are not in your computer yetfor (pckgs_sel in pckgs) { # <5>print(paste("Checking if the package", pckgs_sel, "is installed"))if (!(pckgs_sel %in% pckgs_installed)) {install.packages(pckgs_sel, dependencies =TRUE)print(paste("The", pckgs_sel, "was installed")) } else {print(paste("The", pckgs_sel, "is already installed" ))}}# Load the packageslapply(pckgs, library, character.only =TRUE) # <6> ```1. Selecione os pacotes necessários;2. Instale os pacotes (1st way);3. Ative os pacotes (1st way);4. Identifique os pacotes já instalados no R (2nd way);5. Cheque e instale apenas os pacotes que não estão em seu computador (2nd way);6. Ative os pacotes de interesse (2nd way);## Obtendo e investigando os dados: usando os pacotes [GEOBR]{.underline} e [CENSOBR]{.underline}Diferentes são os caminhos para acessar e manipular dados no R. A reconstrução manual da base dentro do próprio ambiente, com a transcrição de dados ainda não digitalizados, é um exemplo. Registre-se, porém, que quanto maior for o volume de dados, mais demorada e suscetível a erros será essa tarefa. Por esse motivo, costuma-se evitar esse tipo de abordagem.Outra opção consiste em salvar um conjunto de dados já tabulado por alguma instituição (IBGE, IPEA, Fundação SEADE, CEM USP, etc.) em um computador pessoal e abri-lo no ambiente do R. O IBGE, por exemplo, disponibiliza diferentes recursos e plataformas com essa finalidade: i) a seção do *site* da instituição voltada aos [censos demográficos](https://www.ibge.gov.br/estatisticas/sociais/populacao/22827-censo-demografico-2022.html?=&t=o-que-e); ii); o seu sistema de recuperação de informações, o [SIDRA](https://sidra.ibge.gov.br/), ou, iii) o acesso ao servidor do IBGE via [FTP](https://ftp.ibge.gov.br/).Por fim, mas sem esgotar o assunto, o acesso a dados pode ser feito por meio de pacotes criados especificamente para esse fim. Com uma vasta gama de casos no R, este é o caminho que será explorado aqui. Mais especificamente, serão utilizados o [CENSOBR](https://ipeagit.github.io/censobr/articles/censobr.html), que fornece dados cenistários tabulares (tabelas), e o [GEOBR](https://ipeagit.github.io/geobr/), que disponibiliza dados geoespaciais. A partir desses de ambas as bases, os dados de interesse serão integrados, de forma a incorporar a dimensão territorial na análise.Com vistas a tornar a presente exploração mais facilmente replicável a outros contextos, a seguir dois objetos são criados: i) um para definir a escala na qual a área de interesse está inserida - no presente caso, dado que a região de interesse é a Liberdade, o município de São Paulo será escolhido - e ii) o outro para o ano do censo de interesse. Iniciando a análise para o ano de 2010, com esse tipo de procedimento bastaria mudar duas informações, a escala e o ano, e todo o restante do código será gerado automaticamente, mas agora com novos dados.```{r}#| label: vars_to_reuse#| output: false# Let's create a list of variables to reuse the code## Select the municipality(ies)' name(s)mun_name ="São Paulo"## Select the census demographic yearcensus_year =2010# Possible years: 1960, 1970, 1980, 1991, 2000, 2010. See: https://ipeagit.github.io/censobr/articles/censobr.html```O próximo passo consiste em descobrir e escolher quais variáveis do censo retratam a questão e/ou o fenômeno a ser analisado (no presente caso, a raça/cor). Para isso, deve-se recorrer ao dicionário de variáveis.Antes, porém, é importante relembrar que os dados censitários demográficos produzidos pelo IBGE são disponibilizados a partir de dois grandes tipos: os **microdados** (dados da amostra) e os **agregados por setor censitário** (dados do universo)[^2]. Ambos os dados podem ser acessados por meio do pacote [CENSOBR](https://ipeagit.github.io/censobr/articles/censobr.html)[^3], ainda que o foco da presente exploração baseie-se nos microdados, como anteriormente sinalizado.[^2]: Ainda que sejam mais usalmente utilizados, alguns dados censitários também são disponibilizados em outros formatos, como as grades estatísticas(https://mapasinterativos.ibge.gov.br/grade2022/default.html).[^3]: Para identificar quais são, efetivamente, os dados disponibilizados para cada um dos censos, visite: <https://ipeagit.github.io/censobr/articles/censobr.html>.Assim sendo, conforme ilustra o código a seguir, inicia-se com a escolha do tipo de dado que será analisado (neste caso, os microdados da amostra). Em seguida, o dicionário de variáveis será visitado para a identificação do tema/variáveis de interesse (no presente caso, a questão racial, retratada como cor ou raça).```{r}#| label: choosing_variables#| output: false# Choose the variables## Select the dataset of interestdataset_sel ="population"# <1># Para ver as possibilidades, digite ?censobr::data_dictionary no console e veja o argumento "dataset". Ali podem ser vistas as bases disponibiizadas pelo pacote ("population", "households", "families", "mortality", "emigration", "tracts")## See the variable dictionarydata_dictionary(year = census_year, dataset = dataset_sel) # <2># Possibilities: 1960, 1970, 1980, 1991, 2000, 2010. See: https://ipeagit.github.io/censobr/articles/censobr.html```1. Defina qual base dos microdados será utilizada;2. Baixe o dicionário de variáveies da base selecionada;Observando-se o dicionário de variáveis, algumas variáveis foram escolhidas (ver o quadro a seguir). Primando pela concisão, os critérios para a seleção foram a escala de interesse (V0011) e os limites político-administrativos do dado (V0001 e V0002); a geração da estimativa do número de pessoas (V0010); a possibilidade de ligação dessa base com as demais bases dos microdados (V0300) e, por fim, a inclusão da questão a ser analisada, raça (V0606), a qual se acrescentou o genêro (V0601).| Código das variáveis | Nomenclatura ||----------------------|---------------------------|| V0001 | Unidade da Federação (UF) || V0002 | Cód. do município || V0011 | Área de ponderação || V0300 | Variável de controle || V0010 | Peso amostral || V0606 | Raça ou Cor || V0601 | Sexo |```{r}#| label: vars_cens_2010# Choose the population variables of interest var_cens_pop <-c("V0001", "V0002", "V0011", "V0300", "V0010", "V0606", "V0601")```Escolhidas as variáveis, o passo seguinte consiste em obter os dados propriamente ditos ("baixá-los" para a sessão atual do R). Ao realizar essa tarefa, alguns avisos podem ser gerados. Não se preocupe, porém. A partir da leitura dos avisos, verifica-se que as mensagens geradas não se referem a um erro, mas sim a uma série de orientações padrão.Registre-se, em tempo, que após realizar todo o procedimento de acesso e manipulação para o ano de 2010, adiante o mesmo caminho será replicado com os dados dos censos de 2000 e 1991.::: callout-note## NotaOs dados da amostra do censo demográfico brasileiro costumam ser grandes e pesados, o que implica em um uso bastante intenso da memória RAM. Para lidar com esse comportamento do R (alocação dos dados na memória RAM), uma estratégia interessante é adotada pelo CENSOBR: preparar/estruturar o cômputo e gerá-lo apenas quando ele for explicitamente solicitado (mais detalhes podem ser vistos [aqui](https://ipeagit.github.io/censobr/articles/larger_than_memory.html)).:::```{r}#| label: download_census_2010#| output: false#| warning: false# Download and Select the variables of interest from POP MICRODATA, including RACEmicro_pop_orig <-read_population(year = census_year, columns = var_cens_pop) # 1) if the downloading was stopped before finishing, use "censobr::censobr_cache(delete_file = "2000_population_v0.3.0.parquet")" to exclude it from your computer before running the code again; 2) for the 2010 census, the argument 'add_labels = "pt"' transform the categories codes of variabels into its labels.``````{r}#| label: race_distrib_2010# Compute the total population for the municipality, weighting area (AP) and household by race## Select the municipality of interest and load the pop datamicro_pop <- micro_pop_orig |># <1>filter(V0001 =="35"& V0002 =="50308") |># <2>collect() |># <3># mutate(V0624 = as.numeric(V0624)) |>clean_names() # <4>glimpse(micro_pop) # <5>```1. Selecione a base de dados de interesse e crie um novo objeto para armazenar o resultado das operações a seguir;2. Filtre os dados, escolhendo apenas os que se referem ao município de São Paulo;3. "Traga" os dados para a sessão atual do R;4. Uniformize o nome das variáveis (padrão adotado: letras mínusculas, com o espaço entre as palavras preenchido pelo símbolo "\_"), e,5. Observe o resultado gerado.A partir do resultado obtido e da padronização adotada pelas funções do *Tidyverse*, é possível observar rapidamente a estrutura da tabela (552307 linhas/observações e 7 colunas/variáveis), o tipo de dado presente em cada coluna, bem como os primeiros valores para cada uma das variáveis.## Analisando os dados: um retrato para a escala municipal.Com os dados em mãos, a investigação propriamente dita sobre o comportamento da questão racial pode ir adiante. Nesse sentido, inicialmente será computada a distribuição da variável raça/cor para todo o município. Em seguida, o mesmo procedimento será realizado, mas dessa vez considerando-se a escala de maior detalhe do dado: a área de ponderação. Nesse momento, procurar-se-á entender como a distribuição da raça/cor se dá em diferentes regiões do território paulistano. Por fim, serão identificadas e analisadas as áreas de ponderação que abrangem a região de interesse - e que serão descobertas mais à frente.A seguir, inicia-se o cômputo para o município, como um todo. Para facilitar a interpretação, algumas transformações são realizadas na base (conversão de tipos de dados e criação de novas variáveis, por ex.).```{r}#| label: count_race_by_mun#| output: FALSE# Compute the RACE distribution by MUNrace_by_mun_2010 <- micro_pop |># <1>mutate(v0606 =factor(v0606),raca_cor_nome =factor(case_when( v0606 ==1~"Branca", v0606 ==2~"Preta", v0606 ==3~"Amarela", v0606 ==4~"Parda", v0606 ==5~"Indígena", v0606 ==9~"Ignorado")) ) |># <2>group_by(v0606, raca_cor_nome) |># <3>summarise(tot_peop_peso =sum(v0010), tot_peop_orig = dplyr::n()) |># <4>rename(raca_cor = v0606) |># <5>ungroup() |># <6>mutate(prop_race =100* tot_peop_peso/sum(tot_peop_peso)) # <7># See the resultrace_by_mun_2010 # <8>```1. Selecione a base e crie um objeto para guardar as informações sobre raça/cor em todo o município de São Paulo;2. Transforme o tipo da variável raça/cor (de *character* para *fator*) e crie uma nova variável (coluna). Neste caso, as categorias de raça/cor são codificadas com nomes (preta, indígena, branca, etc.), e não mais números;3. Defina cada uma das raças/cores como grupos para as operações a seguir;4. Compute as estimativas da população (*tot_peop_peso*) e o número de casos amostrados por grupo criado;5. Renomeie a variável original de raça/cor (v0606);6. Desagrupe os dados (caso queira entender o impacto desse passo, acrescente o símbolo de comentário no inicío dessa linha ("\#"), indicando para o R que o dado deve continuar agrupado; rode o código e veja o resultado produzido);7. Compute as proporções de pessoas para cada raça/cor e8. Observe o resultado (quantidade e proporção de pessoas para cada raça/cor)Os dados gerados permitem que se construa um primeiro retrato sobre o total de pessoas por raça/cor no município de São Paulo em 2010. A atual forma pode, contudo, ser alvo de melhorias. Assim sendo, propõe-s uma nova tabela para os dados recém-obtidos. Nela, como pode ser visto, existem menos variáveis, os nomes das variáveis são mais intuitivos (facilitando a leitura), os dados foram reordenados - do grupo com mais pessoas para o que possui menos - e ela é esteticamente mais atraente. Tais medidas, facilmente implementadas, ajudam a manter o foco no que realmente importa e facilitam a leitura e compreensão dos dados.::: callout-note## NotaTão relevante quanto a geração de dados é a comunicação dos achados - algo que, aos poucos e na medida do possível, será explorado no presente texto. Isso porque, caso a sua publicização não seja adequada, o impacto gerado, na melhor das hipóteses, deixará de atingir toda a sua potencialidade. Ou seja, não desconsidere esse fator!:::```{r}#| label: table_race_by_mun# Adjust and make a new table race_by_mun_2010 |># <1>select(raca_cor_nome, tot_peop_peso, prop_race) |># <2>rename("Raça ou cor"= raca_cor_nome, "Total de pessoas"= tot_peop_peso, "Proporção (%)"= prop_race) |># <3>mutate(across(.cols =`Total de pessoas`, .fns = round),across(.cols =`Proporção (%)`, .fns =~round(., digits =2))) |># <4>arrange(desc(`Proporção (%)`)) |># <5>gt() # <6>```1. Selecione a base de dados gerada;2. Escolha apenas as variáveis de interesse;3. Renomeie as variáveis;4. Arrendonde os valores referentes ao total de pessoas e à proporção;5. Ordene os dados da maior proporção de pessoas para a menor, e,6. Gere uma tabela mais visualmente atrativa;Outra forma bastante interessante para a visualização de dados e compreensão daquilo que se quer entender baseia-se no uso de gráficos. Para o presente caso, a opção mais apropriada seria o gráfico de barras. E como forma de explorar parte dos elementos que podem compô-lo, optou-se por i) adotar um título, subtítulo e fonte, e, ii) modififcar os valores dos eixos e a cor de fundo. Saliente-se, porém, que o uso de cor fazendo referência às raças ou mesmo o título adotado (mais descritivo e geral) poderiam seguir estratégias distintas e talvez mais interessantes, a depender do contexto e objetivo perseguidos - enfatizando o grupo de interesse, por exemplo[^4].[^4]: A discussão sobre visualização de dados e *Storytelling* com dados é vasta e não será aqui abordada de forma mais profunda. Uma referência bastante conhecida nesse campo é o livro de Cole N. Knaflic, *Storytelling com dados*.```{r}#| label: graph_raca_by_mun#| fig-align: "center"# Create a graphic for the race distribution## Parameters to reusetitle_grap ="Distribuição de pessoas por cor ou raça"subtitle_grap ="Município de São Paulo, 2010"data_orig_grap ="IBGE, Censo 2010"# ap_sel <- c(3550308005001, 3550308005007, 3550308005008)## Municipalityrace_mun_graph <- race_by_mun_2010 |># <1>ggplot(aes(x =fct_reorder(raca_cor_nome, tot_peop_peso, .desc = T), y = tot_peop_peso, fill = raca_cor_nome)) +# <2>geom_col(show.legend = F) +# <3>geom_text(aes(label =round(tot_peop_peso)),vjust =-0.5,hjust =0.5,size =4,fontface ="bold",# colour = "#3b3938" ) +# <4>geom_text(aes(label =str_c("(", round(prop_race, 2), "%)")),vjust =1.25,hjust =0.5,size =3.5) +# <5>labs(title = title_grap,subtitle = subtitle_grap,caption = data_orig_grap,# x = "(Cor ou raça)",# y = "(Número de pessoas)" ) +# <6>scale_fill_manual(values =c("yellow", "#fee6ce", "lightgrey", "#bf812d", "#8c510a", "#5e3814")) +# <7>scale_y_continuous(breaks =c(0, 2000000, 4000000, 6000000),labels =c("0", "2 Mi", "4 Mi", "6 Mi")) +# <8># scale_fill_viridis_d(direction = 1) +theme_classic(base_size =14) +# <9>theme(axis.ticks.x =element_blank(),# axis.text.x = element_blank(),axis.ticks.y =element_blank(),# axis.text.y = element_blank(),axis.title =element_blank() # element_text(colour = "grey", size = 7.5)) )# Look the graphicrace_mun_graph # <10>```1. Defina qual será a base utilizada para a criação do gráfico e crie um objeto para salvar o resultado gerado a seguir;2. Selecione quais variáveis serão expostas no gráfico (eixos x e y);3. Escolha o gráfico de barras como opção de representação;4. Defina a localização dos totais de pessoas nas barras;5. Defina a localização da proporção de pessoas nas barras;6. Defina quais serão o título, subtítulo e fonte;7. Defina cores específicas para cada uma das raças (barras);8. Defina novos intervalos para o eixo y (total de pessoas);9. Escolha como o fundo e os elementos dos eixos devem ser visualizados, e,10. Apresente o gráfico.A partir da tabela e do gráfico, verifica-se, por exemplo, que cerca de 3/5 (60,6%) da população paulistana se autodeclarou branca em 2010. A população negra (parda + preta), por sua vez, respondeu por 37% de todos os paulistanos e paulistanas. No extremo oposto encontram-se as pessoas com algum tipo ascendência dos povos asiáticos (amarelos) e à população indígena. Presentes em nosso território antes da colonização europeia, os povos originários do Brasil representavam apenas 0,1% dos e das paulistanas em 2010, totalizando quase treze mil pessoas.## Analisando os dados: avançando no entendimento sobre a distribuição da raça/cor nas diferentes partes do território municipal (áreas de ponderação)De forma a aprofundar o conhecimento sobre a área de interesse aqui tratada (região da Liberdade), a partir desse momento passa-se a explorar a distribuição da raça/cor por área de ponderação. Ao revisitar a temática em uma escala mais detalhada, comparações entre regiões tornam-se possíveis, com novos subsídios e/ou padrões podendo ser revelados (para o município e para a área de interesse).A seguir, o código gera a distribuição da população por raça/cor para cada uma das áreas de ponderação do município de São Paulo.```{r}#| label: race_distrib_ap_mun_sp# Compute the RACE distribution by APrace_by_ap_2010 <- micro_pop |>mutate(v0606 =factor(v0606),v0011 =factor(v0011) ) |>group_by(v0011, v0606, .drop =FALSE) |>summarise(tot_peop_peso =sum(v0010), tot_peop =n()) |>mutate(prop_race =100*tot_peop_peso/sum(tot_peop_peso),raca_cor_nome =factor(case_when( v0606 ==1~"Branca", v0606 ==2~"Preta", v0606 ==3~"Amarela", v0606 ==4~"Parda", v0606 ==5~"Indígena", v0606 ==9~"Ignorado")) ) |>relocate(ap = v0011, raca_cor = v0606, raca_cor_nome) # Show the resultrace_by_ap_2010```O resultado produzido está no que se costuma chamar de *base ou tabela de forma longa*. Mais adequada para a manipulação de dados, percebe-se que para cada área de ponderação são apresentadas todas as categorias da variável raça/cor, dispostas verticalmente, bem como os seus valores. Tomando-se como exemplo a primeira área de ponderação, 3550308005001, verifica-se que a primeira linha é destinada à raça branca, a segunda à preta, a terceira à amarela e assim por diante. Essa disposição é, então, retomada quando se inicia a segunda área de ponderação, 3550308005002, com a sétima linha apresentando os dados para a raça branca, a oitava para a raça preta, etc. Tal forma, saliente-se, nem sempre facilita a visualização e o entendimento do que se quer investigar.Tendo isso em vista, a seguir os mesmos dados serão apresentados a partir da chamada *forma ampla ou larga*. Como poderá ser visto, dessa vez cada área de ponderação ocupa apenas uma linha da tabela. As categorias da variável raça/cor, por sua vez, são transpostas para as colunas.```{r}#| label: race_distrib_ap_mun_sp_transp# Transpose the data into a wider table race_by_ap_2010_wider <- race_by_ap_2010 |># <1>pivot_wider(id_cols = ap, names_from = raca_cor, values_from =c(tot_peop_peso, prop_race)) |># <2>set_names("ap", "branca", "preta", "amarela", "parda", "indigena", "ignorado", "branca_prop", "preta_prop", "amarela_prop", 'parda_prop', "indigena_prop", "ignorado_prop") |># <3> relocate("ap", "branca", "parda", "preta", "amarela", "indigena", "ignorado", "branca_prop", 'parda_prop', "preta_prop", "amarela_prop", "indigena_prop", "ignorado_prop") |># <4> ungroup() |># <5>mutate(tot_pop = branca + parda + preta + amarela + indigena + ignorado) # <6># See the first version of the wider tablerace_by_ap_2010_wider # <7># Look only to the number of people (absolute values) by AP and racehead(race_by_ap_2010_wider[c(1:7, 14)], n =10) |># <8>mutate(across(.cols =!ap, .fns = round)) |>rename(Branca = branca, Parda = parda, Preta = preta, Amarela = amarela, `Indígena`= indigena, Ignorado = ignorado, Total = tot_pop) |>gt(rowname_col ="ap")# Now consider only the proportion of people (relative values) by AP and racehead(race_by_ap_2010_wider[c(1, 8:14)], n =10) |># <9>rename(`Branca (%)`= branca_prop, `Parda (%)`= parda_prop, `Preta (%)`= preta_prop, `Amarela (%)`= amarela_prop, `Indígena (%)`= indigena_prop, `Ignorado (%)`= ignorado_prop, Total = tot_pop) |>gt(rowname_col ="ap")# write_csv2(race_by_ap_2010_wider, file = here(file.path("2010", "Gerados", "Tabelas", "raca_ap_sp_2010.csv")))```1. Selecione a base e crie um objeto para salvar os dados em formato longo;2. Transforme as categorias da variável raça/cor, originalmente empilhadas, em colunas;3. Adote novos nomes (mais intuitivos) para as colunas;4. Mude a ordem das colunas;5. Desagrupe os dados;6. Crie uma coluna e compute a população total das AP (soma de todas as raças mais os casos "ignorado");7. Observe os dados dispostos na nova forma e note que a base apresenta tanto os dados absolutos quanto os relativos;8. Observe os resultados para as dez primeiras áreas de ponderação, considerando apenas o número de pessoas (volume) para cada cor/raça (perceba o arredondamento dos valores praticado), e,9. Observe os resultados para as dez primeiras áreas de ponderação, mas agora considerando apenas a proporção de pessoas para cada cor/raça.A partir das últimas tabelas, que apresetam os *valores absolutos* (número total/volume/montante de pessoas) e *relativos* (proporção de pessoas), verifica-se uma disposição dos dados mais amigável. Um desafio persiste, porém: o município de São Paulo é composto por 310 áreas de ponderação. Ou seja, a tabela é constituída por 310 linhas, tornando a apreensão do todo difícil.Em situações desse tipo, com bases de dados extensas, usualmente recorre-se a estratégias para sintetizá-los e explicitar eventuais padrões. Uma delas, inclusive, já foi explorada: o uso de *ferramentas baseadas em visualização de dados*, como os gráficos. A ela, some-se a geração de medidas *síntese de localização*, tal qual a famigerada *média*, e *de dispersão*, dentre as quais uma das mais conhecidas é o *desvio padrão*.A seguir, dois tipos de gráficos (*"pontos"* e *"boxplot + violino"*) e uma tabela (composta por medidas de resumo) serão apresentados. Mais do que replicar as mesmas informações em formatos distintos, o que se espera é que eles se complementem e possibilitem uma leitura mais rica e acurada.Iniciando a exploração com os gráficos, forma mais intuitiva, almeja-se verificar se alguns indícios ou padrões revelam-se a partir de uma análise visual. A partir das intuições encontradas e/ou questionamentos levantados (lembre-se: os questionamentos são a base da ciência!), em um segundo momento serão computados elementos "mais precisos" (estatísticas) para uma melhor descrição e caracterização da distribuição espacial da raça/cor, agregados em formato de tabela.```{r}#| label: graf_metrics_all_ap_mun_sp#| fig-align: "center"#| out-width: "100%" #| out-height: "90%"# Create a graphic representing the race distribution with a dot plot (here, some noise is added)graf_race_ap_2010_pnt0 <- race_by_ap_2010 |>ggplot(aes(x =fct_rev(fct_reorder(raca_cor_nome, tot_peop_peso, median)), y = tot_peop_peso)) +geom_point(alpha =0.4, shape =1) +labs(x =NULL,y =NULL) +theme_classic(base_size =14) +theme(# axis.ticks.x = element_blank(),axis.ticks.y =element_blank()) +coord_flip()# Create a graphic representing the race distribution with a dot plotgraf_race_ap_2010_pnt <- race_by_ap_2010 |># <1> ggplot(aes(x =fct_rev(fct_reorder(raca_cor_nome, tot_peop_peso, median)), y = tot_peop_peso)) +# <2> geom_point(position ='jitter', alpha =0.4, shape =1) +# <3> labs(x =NULL,y =NULL) +# <4> theme_classic(base_size =14) +# <5> theme(# axis.ticks.x = element_blank(),axis.ticks.y =element_blank()) +coord_flip() # <6> # Create a graphic representing the race distribution with a violin and boxplotgraf_race_ap_2010_res <- race_by_ap_2010 |># <1> ggplot(aes(x =fct_rev(fct_reorder(raca_cor_nome, tot_peop_peso, median)), y = tot_peop_peso)) +# <2> geom_boxplot() +# <3> geom_violin(scale ="width", fill =NA, color ="darkorange", alpha =0.7) +# <3> labs(x =NULL,y =NULL) +# <4> theme_classic(base_size =14) +# <5> theme(# axis.ticks.x = element_blank(),axis.ticks.y =element_blank()) +coord_flip() # <6> # Plot and compare both graphics(graf_race_ap_2010_pnt0 / graf_race_ap_2010_pnt / graf_race_ap_2010_res) # <7>```1. Selecione a base de dados e crie um objeto para salvar o gráfico;2. Defina quais serão as variáveis que aparecerão no gráfico;3. Escolha o tipo de gráfico/representação dos dados. Note: nos dois primeiros casos, gera-se um *gráfico de pontos*, com os dados do segundo levemente deslocados. Já no segundo apresenta-se uma sobreposição entre o *gráfico de violino* e *boxplot*;4. Exclua o nome dos eixos dos gráficos;5. Defina alguns elementos visuais do gráfico, como o tamanho das letras, a cor do fundo e a exclusão dos pequenos traços que ligam os valores aos eixos;6. Inverta o eixo dos gráficos, e,7. Defina a ordem em que os gráficos serão dispostos.Como pode ser visto, três gráficos são apresentados. Note-se, contudo, que tanto o primeiro quanto o segundo tratam de um mesmo tipo de representação (*gráfico de pontos*). Neles, os pontos indicam qual é a população total de cada uma das áreas de ponderação por raça/cor - a diferença, aqui explorada para fins didáticos, reside no fato do segundo gráfico apresentar dados ligeiramente deslocados de seu valor real, uma técnica usada para facilitar a análise e a apreensão de padrões.Obervando-se a localização dos pontos, verifica-se, por exemplo, que enquanto as populações preta, indígena e amarela apresentam valores mais concentrados (maior número de pontos próximos e/ou sobrepostos, reforçando a cor preta), no caso das populações pardas e branca o total de pessoas nas áreas de ponderação está mais disperso (há uma maior variabilidade). Grosso modo, poder-se-ia dizer que o tamanho das populações preta, indígena e amarela, por área de ponderação, é mais parecido do que o encontrado para as populações branca e parda.Considerando-se essa mesma separação, é seguro afirmar que todas as áreas de ponderação do município de São Paulo (ponto preto) possuem menos de 10.000 habitantes pretos, indígenas ou amarelos - limiar ultrapassado pelos residentes brancos e pardos em várias áreas de ponderaçao. Também é possível notar que, diferentemente de todas as outras populações, as áreas de ponderação com o menor número de pessoas brancas somam cerca de 10.000 pessoas - exceção feita a dois casos.O segundo gráfico, composto pela sobreposição entre o *gráfico de violino (linha laranja)* e o *boxplot* , busca representar a distribuição da população, por raça/cor e áreas de ponderação, de outra forma. Iniciando-se a leitura pelo *boxplot*, destaque-se que alguns elementos dessa representação costumam ser sempre observados. Um deles é a sua caixa, que perfaz a metade central de todo o conjunto dos dados. Com isso, é possível estimar, por exemplo, que metade da população branca varia entre 16 e 26 mil pessoas, considerando-se a sua distribuição por área de ponderação. Já no caso da população parda esses valores parecem variar entre 5.000 e 15.000 pessoas (não se preocupe com a precisão nesse momento, pois os números corretos serão observados na tabela produzida mais adiante).O *boxplot* fornece, ainda, ao menos duas outras informações interessantes. A primeira diz respeito à linha vertical central da caixa, que indica onde se encontra a mediana. Ordenando-se os totais das populações do menor para o maior valor, a mediana é o valor que divide o conjunto de dados ao meio[^5]. No caso da população preta, por exemplo, esse valor parece estar próximo a 2.500 pessoas.[^5]: A mediana, diferentemente da média, é muito menos influenciada pela existência de valores discrepantes (*outliers*), motivo pelo qual é considerada uma medida de tendência central (ou, de forma mais ampla, medida de localização) robusta.A outra informação de interesse está relacionada aos pontos que aparecem para algumas raças/cores. Neste caso, eles indicam as áreas de ponderação cuja população é muito diferente de todo o restante - esses casos são chamados de pontos discrepantes ou *outliers.* Percebe-se, por exemplo, que a raça amarela possui algumas áreas de ponderação com uma população muito maior do que o comportamento geral dessa raça no município. Já no extremo oposto encontra-se a populaçao preta, que não apresenta nenhuma área de ponderação que foge do comportamento geral dessa raça/cor.Complementando os achados do *boxplot*, novos elementos obtidos por meio do gráfico de violino podem ser acrescentados. Ao representar de forma mais contínua a distribuição das populações por raça/cor e área de ponderação, é possível notar, por exemplo, que a população parda apresenta dois pequenos picos, um logo abaixo de 5.000 pessoas e outro em torno de 14.000 pessoas. As populações preta e branca, por sua vez, parecem apresentar um único pico. Com um olhar um pouco mais treinado, também é possível notar uma ligeira concentração de casos antes da mediana para essas raças/cores - compare o tamanho das caudas do gráfico antes e depois da linha da mediana.De forma a tornar mais precisos os indícios, intuições e questões gerados a partir da visualização dos dados e avançar na busca de novos achados, a seguir serão computadas algumas estatísticas para cada uma das raças. Os resultados, por sua vez, são agrupados em uma mesma tabela.```{r}#| label: tab_metrics_all_ap_mun_sp#| fig-align: "center"# Compute some metrics to describe the data## Compute the measures by racebranca_mtrc <-summary(race_by_ap_2010_wider$branca) # <1> parda_mtrc <-summary(race_by_ap_2010_wider$parda) # <1>preta_mtrc <-summary(race_by_ap_2010_wider$preta) # <1>amarela_mtrc <-summary(race_by_ap_2010_wider$amarela) # <1>indigena_mtrc <-summary(race_by_ap_2010_wider$indigena) # <1>ignorado_mtrc <-summary(race_by_ap_2010_wider$ignorado) # <1>## Create a table with all race metricstab_race_metrcs_ap <-bind_rows(branca_mtrc, parda_mtrc, preta_mtrc, amarela_mtrc, indigena_mtrc, ignorado_mtrc) |># <2> as.data.frame() |># <3> mutate(raca_cor =c("Branca", "Parda", "Preta", "Amarela", "Indigena", "Ignorado"),across(.cols =!raca_cor, .fns = round)) |># <4> relocate(raca_cor) |># <5> set_names("Raça ou cor", "Menor valor", "1o. Quartil", "Mediana", "Média", "3o. Quartil", "Maior valor") # <6>tab_race_metrcs_ap |>gt(rowname_col ="Raça ou cor") # <7>```1. Compute algumas métricas para cada uma das raças/cores;2. Junte todas as métricas calculadas ("colando" as linhas);3. Transforme a junção anterior em um data.frame ("tabela");4. Acrescente uma variável para a raça/cor e arredonde os valores da população;5. Coloque a variável raça/cor na primeira posição da base, e,6. Defina nomes mais intuitivos para as variáveis, e,7. Crie uma tabela mais visualemente atrativa.\|A partir dos valores da tabela, verifica-se que as percepções obtidas por meio dos gráficos é corroborada pelos números. Um dos achados obtidos visualmente indicava uma maior concentração dos valores das populações preta, amarela e indígena por área de ponderação - levando, a grosso modo, à noção de que a distribuição dessas raças ao longo do território era mais parecido (ou menos diferente) do que o encontrado para as raças brancas e parda. Recorrendo-se ao *Intervalo Interquaril* (IQR) para quantificar esse comportamento[^6]*,* constata-se que a diferença das populações por área de ponderação para as raças branca e preta é de 9.494 e 10.508 pessoas, respectivamente. Por sua vez, ao se considerar as populações preta, amarela e indígena, essa diferença é de 1.912, 703 e 48 pessoas. Ou seja, mesmo considerando-se a diferença entre a população branca (menor valor do grupo mais disperso, de acordo com o IQR) e a população preta (maior valor do grupo mais concentrado), a dispersão ou variabilidade é cinco vezes maior a favor da raça branca (9.494 pessoas brancas/1.912 pessoas pretas).[^6]: o IQR é uma medida de dispersão robusta que computa a diferença entre os valores do primeiro e terceiro quartis dos dados.Observando-se as menores quantidades de pessoas por raça/cor presentes nas áreas de ponderação (coluna "Menor valor" da tabela), percebe-se que enquanto existe ao menos uma área de ponderação que não possui indígenas - valor que salta para ao menos 25% das áreas de ponderação, dado que o valor do 1º quartil é 0[^7] -, o menor número de pessoas brancas em uma área de ponderação no município é de 4.160. Esse valor, aliás, é maior do que o encontrado em ao menos 75% de todas as áreas de ponderação para as raças/cores preta, amarela e indígena (observe e compare os dados a partir da coluna do 3º quartil).[^7]: Observando-se a tabela com os dados brutos, nota-se que 110, das 310 áreas de ponderação do município de São Paulo, não possuem indígenas residentes (cerca de 35%).Em sentido oposto, ao se considerarem as maiores quantidades de pessoas por raça/cor e área de ponderação (coluna "Maior valor"), agora é possível mensurar e identificar as áreas que possuem as maiores populações preta (6.208 pessoas), amarela (6.940) e indígena (1.005). Dado que a simples comparação desse valor com o do 3º quartil para cada uma dessas raças/cores indica uma diferença não desprezível, pode-se aventar ou suspeitar que algo ocorreu/ocorre nessas porções do território, fomentando essa concentração espacial.Operando-se de forma similar, verifica-se que as estatísticas da tabela especificam as medidas anteriormente obtidas por meio dos gráficos. Dessa forma, as aproximações geradas para os percentis 25º e 75º (medidas/linhas limites da caixa do *boxplot*), bem como para o 50º (mediana, representanda pela linha dentro da caixa), agora são mensuradas e localizadas de forma mais precisa. No caso da população preta, por exemplo, o primeiro, o segundo (mediana) e o terceiro quartis correspondem a 1.274, 2.264 e 3.186 pessoas. Por sua vez, essas mesmas medidas para a população parda perfazem 5.276, 11.051 e 11.120 pessoas.Para finalizar essa etapa de "contextualização regional", duas novas estratégias serão rapidamente exploradas. Enquanto a primeira está baseada no tamanho das áreas de ponderação, como um todo (ou seja, considerando todas as raças/cores), a segunda abordará a questão a partir do tamanho da população negra (pessoas pardas + pessoas pretas).O código a seguir fornece subsísios para a análise das áreas de ponderação (AP) mais populosas. O objetivo será compreender a composição por raça/cor para as cinco áreas com os maiores números de residentes - o número 5 foi escolhido para tornar a análise mais paupável e inteligível a partir dos dados brutos. Note-se, ainda, que um ranqueamento foi criado para auxiliar a leitura.```{r}#| label: tab_rank_pop_ap_mun_sp# Select only the absolute values and rank all the race categoriesrace_by_ap_2010_wider_pos_abs <- race_by_ap_2010_wider |># <1>select(!ends_with("_prop")) |># <2>mutate(branca_rank =min_rank(desc(branca)), # <3>parda_rank =min_rank(desc(parda)),preta_rank =min_rank(desc(preta)),amarela_rank =min_rank(desc(amarela)),indigena_rank =min_rank(desc(indigena)),total_rank =min_rank(desc(tot_pop)),across(.cols =!c(ends_with("_rank"), starts_with("ap")), .fns = round)) |>rename(total = tot_pop) |># <4>arrange(desc(total)) # <5>tab_race_ap5_abs <- race_by_ap_2010_wider_pos_abs |>slice_head(n =5) # <6>tab_race_ap5_abs |>set_names("AP", "Branca", "Parda", "Preta", "Amarela", "Indígena", "Ignorado", "Total", "Branca (Rank)", "Parda (Rank)", "Preta (Rank)", "Amarela (Rank)", "Indígena (Rank)", "Total (Rank)") |># <7># mutate(Negra = Parda + Preta) |># relocate(Negra, .after = Preta) |>gt() # <8># Select only the proportion values and rank all the race categoriesrace_by_ap_2010_wider_pos_prop <- race_by_ap_2010_wider |># <9>select(ap, ends_with("_prop"), tot_pop) |># left_join(race_by_ap_2010_wider_pos_abs[c("ap", "total")], join_by(ap)) |># relocate(.after = ignorado_prop, total) |> mutate(branca_prop_rank =min_rank(desc(branca_prop)),parda_prop_rank =min_rank(desc(parda_prop)),preta_prop_rank =min_rank(desc(preta_prop)),amarela_prop_rank =min_rank(desc(amarela_prop)),indigena_prop_rank =min_rank(desc(indigena_prop)),total_rank =min_rank(desc(tot_pop))) |>rename(total = tot_pop) |>arrange(desc(total))tab_race_ap5_prop <- race_by_ap_2010_wider_pos_prop |>slice_head(n =5) tab_race_ap5_prop |>set_names("AP", "Branca %", "Parda %", "Preta %", "Amarela %", "Indígena %", "Ignorado %", "Total", "Branca % (Rank)", "Parda % (Rank)", "Preta % (Rank)", "Amarela % (Rank)", "Indígena % (Rank)", "Total % (Rank)") |># <7># mutate(`Negra %` = `Parda %` + `Preta %`) |># relocate(`Negra %`, .after = `Preta %`) |>mutate(across(.cols =!c(AP, Total, ends_with("(Rank)")), .fns =~round(., digits =2))) |>gt()```1. Selecione a base de interesse e crie um objeto para salvar os resultados;2. Selecione apenas as variáveis que apresentam os totais populacionais por raça/cor (todas aquelas que não terminavam com "\_prop");3. Ranqueie, considerando a população total, as áreas de ponderação (AP) para cada uma das raça/cores ;4. Adote nomes mais intuitivos para as variáveis;5. Ordene as AP em função do tamanho de suas populações totais;6. Selecione as cinco primeiras AP (mais populosas);7. Defina nomes de variáveis mais intuitivas;8. Gere uma tabela mais visualmente atrativa, e,9. Repita o mesmo procedimento, mas agora considerando as proporções populacionais por raça/cor e área de ponderação.A partir dos dados gerados, verifica-se que as cinco áreas de ponderação (AP) mais populosas do município de São Paulo variam de `r tab_race_ap5_abs$total[1]` a `r tab_race_ap5_abs$total[5]` pessoas (com uma média de `r mean(tab_race_ap5_abs$total)` pessoas). E tal qual ocorre no município, as raças branca e parda concentram os maiores quantitativos de pessoas (cerca de `r race_by_mun_2010 |> filter(raca_cor_nome == "Branca") |> select(prop_race) |> round()` e `r race_by_mun_2010 |> filter(raca_cor_nome == "Parda") |> select(prop_race) |> round()`) nessas áreas, sendo seguidas mais de longe pela pessoas pretas, amarelas e indígenas.Ressalte-se, contudo, que a distância encontrada nesses casos é bem menor. Computando-se duas medidas de tendência central, constata-se que os totais médio e mediano de pessoas brancas dessas cinco AP são de `r mean(tab_race_ap5_abs$branca) |> round()` e `r median(tab_race_ap5_abs$branca) |> round()`. Já no caso das pessoas pardas, eles correspondem a `r mean(tab_race_ap5_abs$parda) |> round()` e `r median(tab_race_ap5_abs$branca) |> round()`.Também é possível verificar que nas duas AP com o maior número de residentes do município (3550308005259 e 3550308005189) ocorre uma inversão entre as raças/cores branca e parda. Totalizando 49,9% (28.449 pessoas) e 44,4% (24.747), a população parda ali presente supera a branca - a leitura espacial a seguir indicará que essas duas AP estão localizadas nos distritos do Lajeado, extremo leste do município, e da Brasilândia, na Zona Norte. Mais: caso se considere a população negra (preta + parda), das cinco AP mais populosas, apenas a 3550308005237 possui mais residentes brancos - com 53% de brancos e 45% de negros, essa área está localizada no distrito do Campo Limpo. Para as quatro AP restantes, os números da população negra variam de 51% do total a 59% (27.992 a 33.649 pessoas, respectivamente).Feitos esses breves comentários, passa-se, agora, a alguns breves comentários baseados no ranqueamento das raças/cores para as cinco AP analisadas. Antes, contudo, é importante reforçar que o ordenamento e a classificação foram realizados do maior valor (que ocupa a posição 1) para o menor (que ocupa a posição 310). Com isso, torna-se possível "olhar para dentro" de cada raça/cor e entender a sua distribuição territorial específica.Consideranço-se apenas os totais populacionais (valores absolutos), verifica-se, de forma geral, que as cinco AP mais populosas também apresentam grandes contingentes de pessoas pardas e negras . Observa-se, por exemplo, que quatro das cinco AP mais populosas do município estão entre as 10 AP mais pardas do município (posições 2, 3, 4 e 10). No caso da população preta, o mesmo ocorre para três dos cinco casos analisados (posições 1, 8 e 5). Apenas para efeito de comparação, a AP que possui o maior número de pessoas brancas (28.194) dentre as 5 AP mais populosas do município ocupa apenas a posição 51 no *ranking* de AP da raça/cor branca.A seguir, as cinco AP analisadas são espacializadas e inseridas dentro dos seus respectivos distritos (limites em roxo e linha preta). Localizadas em diferentes partes do território (zonas Leste, Norte e Sul), percebe-se com relativa facilidade um traço comum: todas se encontram em regiões periféricas do município. Note: para além da legenda, localizada no canto direito superior do "mapa", no canto inferior direito aparece a identificação dessas AP novamente. Esse "botão translúcido", ao ser clicado, leva a um *zoom* da área escolhida no mapa. Para retornar ao *zoom* inicial, clique no botão no canto inferior esquerdo (*Zoom full*).```{r}#| label: map_5_rank_pop_ap_mun_sp# Select the 1st five AP with the highest population## Get the AP spatial limitsap_mun_sp <-read_weighting_area(code_weighting =3550308, year =2010, simplified = F) # <1>## Find out the code of the 1st five AP with the highest population from the aspatial data settop5_ap_abs <- race_by_ap_2010_wider_pos_abs |>slice_head(n =5) # |> pull(ap)## Filter the 1st 5 AP spatial limits of interest ap_top5_pop_geo <- ap_mun_sp |>select(code_weighting, name_muni) |>right_join(top5_ap_abs, join_by(code_weighting == ap)) |>relocate(name_muni) |>arrange(desc(total))ap_top5_pop_geo_pts <- ap_top5_pop_geo |>st_centroid()# Get the district spatial limits for SP municdistrito_mun_sp <-read_neighborhood(year =2010, simplified = F) |>filter(code_muni ==3550308) |>select(abbrev_state, name_muni, code_district, name_district)# See both AP selected and District data together in the space## See the color pallets availabledisplay.brewer.all(n =NULL, type ="all", select =NULL, exact.n =TRUE, colorblindFriendly =TRUE)## Create a map to show the AP limitsmap_top5_ap_pop_lim <-mapview(distrito_mun_sp, zcol ="name_district", color ="gray35", col.regions ="royalblue", alpha.regions =0.4, legend =FALSE) +mapview(ap_top5_pop_geo, zcol ="code_weighting", lwd =2, burst = T, legend =FALSE) ## Create a map to show the AP centroids/pointsmap_top5_ap_pop_pts <-mapview(distrito_mun_sp, zcol ="name_district", color ="gray35", col.regions ="royalblue", alpha.regions =0.4, legend =FALSE) +mapview(ap_top5_pop_geo_pts, zcol ="total", cex ="total", layer.name ="Pop. (total)")# col.regions # col.regions # col.regions = rev(brewer.pal(5, "YlOrRd")))## Show both mapsleafsync::sync(map_top5_ap_pop_lim, map_top5_ap_pop_pts, ncol =2)```Para o desenvolvimento da segunda estratégia, propõe-se uma leitura mais integrada entre os dados e sua distribuição espacial. Mais do que formalizar ou representar de outra forma os achados, agora a espacialização contribuirá mais ativamente para a compreensão do objeto de interesse.Nesse sentido, a seguir serão computados e ordenados os totais e as proporções da população negra por área de ponderação, com destaque para as cinco maiores áreas/populações. Note: ainda que se possa utilizar o ranqueamento já realizado para isso, de forma a explorar a construção de códigos um caminho distinto é proposto.```{r}#| label: tab_rank_black_pop_ap_mun_sp# Select the 5 weighting areas (AP) with the highest black population (absolute values)## Compute the total black population for all 310 APtab_black_ap_abs <- race_by_ap_2010_wider_pos_abs |># <1>mutate(negra = parda + preta,negra_rank =min_rank(desc(negra))) |># <2>relocate(negra, .after = preta) |># <3>relocate(negra_rank, .after = preta_rank) |># <3>arrange(desc(negra)) # <4>## Select only the 5 AP with most Black population tab_black_ap5_abs <- tab_black_ap_abs |>head(5) # <5> ## Create a more attractive tabletab_black_ap5_abs |>select(!ends_with("_rank")) |># <6>set_names("AP", "Branca", "Parda", "Preta", "Negra", "Amarela", "Indígena", "Ignorado", "Total") |># <7># set_names("AP", "Branca", "Parda", "Preta", "Negra", "Amarela", "Indígena", "Ignorado", "Total", "Branca (Rank)", "Parda (Rank)", "Preta (Rank)", "Amarela (Rank)", "Indígena (Rank)", "Total (Rank)") |> gt() # <8># Select the 5 weighting areas with the highest proportion of black people (relative values)## Compute the total black population for all 310 APtab_black_ap_prop <- race_by_ap_2010_wider_pos_prop |># <9>mutate(negra_prop = parda_prop + preta_prop,negra_prop_rank =min_rank(desc(negra_prop))) |>relocate(negra_prop, .after = preta_prop) |>relocate(negra_prop_rank, .after = preta_prop_rank) |>arrange(desc(negra_prop)) tab_black_ap5_prop <- tab_black_ap_prop |>head(5)# Create a more attractive tabletab_black_ap5_prop |>select(!ends_with("_rank")) |>mutate(across(!c(ap, total), .fns =~round(x = ., digits =2))) |>set_names("AP", "Branca (%)", "Parda (%)", "Preta (%)", "Negra (%)", "Amarela (%)", "Indígena (%)", "Ignorado (%)", "Total") |># set_names("AP", "Branca", "Parda", "Preta", "Negra", "Amarela", "Indígena", "Ignorado", "Total", "Branca (Rank)", "Parda (Rank)", "Preta (Rank)", "Amarela (Rank)", "Indígena (Rank)", "Total (Rank)") |> gt()```1. Selecione a base de interesse e crie um objeto para salvar os resultados;2. Adicione duas novas variáveis, uma para a contagem da população negra (var *negra*) e a outra para o seu ranqueamento (var. *negra_rank*);3. Desloque as variáveis criadas;4. Ordene a base em função da população total negra de forma decrescente (do maior para o menor valor);5. Selecione as cinco primeiras AP (cinco maiores populações negras);6. Exclua as variáveis que tratam do ranqueamento para a criação de uma tabela mais limpa;7. Defina nomes de variáveis mais intuitivas;8. Gere uma tabela mais visualmente atrativa, e,9. Repita o mesmo procedimento, mas agora considerando as proporções populacionais por raça/cor e área de ponderação.Para complementar a leitura a partir dos dados totais e proporcionais da população negra no município de São Paulo, o código a seguir ilustra uma forma de espacializá-los. Note: ainda que seja maior do que os trechos anteriores, as linhas de comando buscam, basicamente, i) agregar a informação dos distritos e os dados de raça/cor à camada espacial das áreas de ponderação, e, ii) criar uma representação espacial da distribuição das pessoas negras no município de São Paulo, tanto em quantidade quanto em proporção.```{r}#| label: map_black_pop_ap_mun_sp# Prepare the data to see the black territorial distribution (absolute values/TOTAL POP)## Find out the relationship between weighting areas (AP) and districtsap_mun_sp_with_dstrc <- ap_mun_sp |>st_centroid() |>st_intersection(distrito_mun_sp[c("name_district")]) |>mutate(name_district =factor(name_district)) |>arrange(code_weighting) |>st_drop_geometry()## Add the district info to the AP spatial limitsap_mun_sp_with_dstrc <- ap_mun_sp |>left_join(ap_mun_sp_with_dstrc[c("code_weighting", "name_district")], join_by(code_weighting))## Add the race data set (aspatial) to AP spatial limits (already with districts info) ap_pop_black_abs_geo <- ap_mun_sp_with_dstrc |>select(name_muni, ap = code_weighting, name_district) |>right_join(tab_black_ap_abs, join_by(ap)) |>arrange(desc(negra))## Select the 5 highest black population by AP (now a spatial object with districts info)ap_top5_pop_black_abs_geo <- ap_pop_black_abs_geo |>head(5)# Create the centroids of the 5 highest black population by APap_top5_pop_black_abs_geo_pts <- ap_top5_pop_black_abs_geo |>st_centroid()# Map the black population by AP and highlight the 5 biggest pop/area## Fill all the AP with black populationmap_ap_pop_black_lim <-mapview(ap_pop_black_abs_geo, zcol ="negra", col.regions =brewer.pal(310, "YlOrRd"), lwd =0.15, layer.name ="Pop. (Total)")## Map the five AP with the highest Black populationmap_top_5_ap_pop_black_pts <-mapview(ap_top5_pop_black_abs_geo_pts, zcol ="negra", cex ="negra",color ="grey25",alpha.regions =0, lwd =2,layer.name ="Pop. (5 mais)", legend = F)## Map the SP's district limitsmap_distrito_mun_sp_lim <-mapview(distrito_mun_sp, zcol ="name_district", alpha.regions =0, lwd =0.4, legend =FALSE)## Join the three layers into a unique geospatial representationmap_black_abs_all <- map_distrito_mun_sp_lim + map_ap_pop_black_lim + map_top_5_ap_pop_black_pts# Prepare the data to see the black territorial distribution (relative values/PROPORTIONAL POP) ## Join the AP limits (geospatial) with pop data by AP (aspatial)ap_pop_black_prop_geo <- ap_mun_sp_with_dstrc |>select(name_muni, ap = code_weighting, name_district) |>right_join(tab_black_ap_prop, join_by(ap)) |>mutate(across(.cols =!c("name_muni", "ap", "name_district", "geom"), .fns =~round(x = ., digits =2))) |>arrange(desc(negra_prop))## Select the 5 highest black population proportions by APap_top5_pop_black_prop_geo <- ap_pop_black_prop_geo |>head(5)## Create the centroids of the 5 highest black population proportions by APap_top5_pop_black_prop_geo_pts <- ap_top5_pop_black_prop_geo |>st_centroid()# Map the black population proportion by AP and highlight the 5 biggest pop/area## Fill all the AP with black populationmap_ap_pop_black_prop_lim <-mapview(ap_pop_black_prop_geo, zcol ="negra_prop", col.regions =brewer.pal(310, "YlOrRd"), lwd =0.15, layer.name ="Pop. (%)")## Map the five AP with the highest Black population proportionsmap_top_5_ap_pop_black_prop_pts <-mapview(ap_top5_pop_black_prop_geo_pts, zcol ="negra_prop", cex ="negra_prop",color ="black",alpha.regions =0, lwd =2,layer.name ="Pop. (% 5 most)", legend = F)## Join the three layers into a unique geospatial representationmap_black_prop_all <- map_distrito_mun_sp_lim + map_ap_pop_black_prop_lim + map_top_5_ap_pop_black_prop_pts# Show both maps side by sideleafsync::sync(map_black_abs_all, map_black_prop_all)```Como pode ser visto, o recurso de visualização espacial produzido apresenta dois mapas sincronizados. Enquanto à esquerda é possível ver a classificação das áreas de ponderação (AP) em função dos totais da população negra (parda + preta) residente, à direita a classifição baseia-se nas proporções dessa população residente nas AP. Note-se, ainda, que as linhas cinzas representam os limites das AP e dos distritos municipais.Considerando-se a distribuição da raça negra por áreas de ponderação (AP, representadas por polígonos em cores), ainda que existam diferenças, um padrão parece se repetir em ambos os casos: cores mais claras e próximas ao amarelo ocupam uma porção mais central do município, indicando uma menor presença e concentração dessa população - a área em questão abrange partes da região central (distritos da Santa Cecília e Consolação, por ex.), oeste (Barra Funda, Perdizes e Pinheirosm por ex.) e sudoeste-sul (Jardim Paulista, Moema, Itam Bibi e Vila Mariana). Por sua vez, conforme se avança para as bordas ou periferia de São paulo, as cores tendem a se aproximar do vermelho, apontando para um aumento da população negra em áreas mais periféricas do munícipio.Observando-de de forma mais atenta, é possível verificar que tal padrão é mais heterogêneo quando se considera o total de pessoas negras em cada uma das AP (mapa à esquera) e mais homogêneo quando se analisa a distribuição territorial dessa popoulação a partir das proporções. Neste último caso, inclusive, o padrão centro-perfieria aparece de forma bastante clara.Esse padrão(que traço parece estar presente em ambos os casos.tanto o total de pessoas por AP ()## Analisando os dados: da identificação à caracterização da região de interesseConhecida a distribuição da questão racial para o município de São Paulo, como um todo, bem como entre regiões, o próximo passo consiste em observar a distribuição da questão racial em nossa área de interesse (região da Liberdade). O primeiro passo consiste em identificar quais são as áres de ponderação que abrangem a região. Recorrendo a um mapa interativo para essa finalidade, o objetivo será identificar, a partir da navegação espacial, quais são os códigos das áreas de ponderação qu recobrem a área de interesse.```{r}#| label: download_ap# Download the São Paulo weighting area limits ap_mun_sp <-read_weighting_area(code_weighting =3550308, year =2010) # <1>```1. Baixe os limites das áreas de ponderação, definindo o município e o ano;```{r}#| label: download_district# Download the São Paulo district limits distrito_mun_sp <-read_neighborhood(year =2010) |># <2>filter(code_muni ==3550308) |>select(abbrev_state, name_muni, code_district, name_district)```2. Baixe os limites dos distritos, definindo o município, o ano e as variáveis de interesse, e,```{r}#| label: finding_ap# Plot the weighting areas and district limitsmapview(ap_mun_sp, zcol ="code_weighting", legend =FALSE) +mapview(distrito_mun_sp, zcol ="name_district", alpha.regions =0, legend =FALSE) # <3>```3. Plote os limites de ambos os dados.Como pode ser visto, o recurso gerado possibilita não só a navegação digital pelo território - com o deslocamento pelas áreas da cidade e o uso do *zoom* -, mas também permite escolher a imagem de fundo e as camadas geoespaciais (áreas de ponderação e/ou distritos) a serem visualizadas. Para isso, basta clicar no botão com o desenho de retângulos empilhados no lado esquerdo superior da janela e realizar as escolhas. Note: os vazios e/ou a superposição entre polígonos da mesma camada são resultado apenas da opção para deixar a visualização mais leve. No dado original, contudo, eles não existem (em linguagem mais técnica, não há problemas de topologia).A partir da interação com o mapa digital, verifica-se que três são as áreas de ponderação (AP) de interesse, com duas pertencendo ao distrito da Liberdade (3550308005007 e 3550308005008) e a outra ao distrito da Sé (3550308005001).